blob: f67065dec4b12b8abf6c27385d3c664df3baa739 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/bootstrapper.h"
Steve Blocka7e24c12009-10-30 11:49:00 +00006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/accessors.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/api-natives.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/code-stubs.h"
10#include "src/extensions/externalize-string-extension.h"
11#include "src/extensions/free-buffer-extension.h"
12#include "src/extensions/gc-extension.h"
13#include "src/extensions/statistics-extension.h"
14#include "src/extensions/trigger-failure-extension.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015#include "src/heap/heap.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016#include "src/isolate-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000017#include "src/snapshot/natives.h"
18#include "src/snapshot/snapshot.h"
19#include "src/wasm/wasm-js.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000020
21namespace v8 {
22namespace internal {
23
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024Bootstrapper::Bootstrapper(Isolate* isolate)
25 : isolate_(isolate),
26 nesting_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027 extensions_cache_(Script::TYPE_EXTENSION) {}
Steve Block44f0eee2011-05-26 01:26:41 +010028
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029template <class Source>
30Handle<String> Bootstrapper::SourceLookup(int index) {
31 DCHECK(0 <= index && index < Source::GetBuiltinsCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032 Heap* heap = isolate_->heap();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000033 if (Source::GetSourceCache(heap)->get(index)->IsUndefined()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +010034 // We can use external strings for the natives.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035 Vector<const char> source = Source::GetScriptSource(index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010036 NativesExternalStringResource* resource =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 new NativesExternalStringResource(source.start(), source.length());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038 // We do not expect this to throw an exception. Change this if it does.
39 Handle<String> source_code = isolate_->factory()
40 ->NewExternalStringFromOneByte(resource)
41 .ToHandleChecked();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040042 // Mark this external string with a special map.
43 source_code->set_map(isolate_->heap()->native_source_string_map());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 Source::GetSourceCache(heap)->set(index, *source_code);
Steve Blocka7e24c12009-10-30 11:49:00 +000045 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046 Handle<Object> cached_source(Source::GetSourceCache(heap)->get(index),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047 isolate_);
Steve Blocka7e24c12009-10-30 11:49:00 +000048 return Handle<String>::cast(cached_source);
49}
50
51
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052template Handle<String> Bootstrapper::SourceLookup<Natives>(int index);
53template Handle<String> Bootstrapper::SourceLookup<ExperimentalNatives>(
54 int index);
55template Handle<String> Bootstrapper::SourceLookup<ExperimentalExtraNatives>(
56 int index);
57template Handle<String> Bootstrapper::SourceLookup<ExtraNatives>(int index);
58
59
Steve Blocka7e24c12009-10-30 11:49:00 +000060void Bootstrapper::Initialize(bool create_heap_objects) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 extensions_cache_.Initialize(isolate_, create_heap_objects);
62}
63
64
65static const char* GCFunctionName() {
66 bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0;
67 return flag_given ? FLAG_expose_gc_as : "gc";
68}
69
70
71v8::Extension* Bootstrapper::free_buffer_extension_ = NULL;
72v8::Extension* Bootstrapper::gc_extension_ = NULL;
73v8::Extension* Bootstrapper::externalize_string_extension_ = NULL;
74v8::Extension* Bootstrapper::statistics_extension_ = NULL;
75v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL;
76
77
78void Bootstrapper::InitializeOncePerProcess() {
79 free_buffer_extension_ = new FreeBufferExtension;
80 v8::RegisterExtension(free_buffer_extension_);
81 gc_extension_ = new GCExtension(GCFunctionName());
82 v8::RegisterExtension(gc_extension_);
83 externalize_string_extension_ = new ExternalizeStringExtension;
84 v8::RegisterExtension(externalize_string_extension_);
85 statistics_extension_ = new StatisticsExtension;
86 v8::RegisterExtension(statistics_extension_);
87 trigger_failure_extension_ = new TriggerFailureExtension;
88 v8::RegisterExtension(trigger_failure_extension_);
89}
90
91
92void Bootstrapper::TearDownExtensions() {
93 delete free_buffer_extension_;
94 free_buffer_extension_ = NULL;
95 delete gc_extension_;
96 gc_extension_ = NULL;
97 delete externalize_string_extension_;
98 externalize_string_extension_ = NULL;
99 delete statistics_extension_;
100 statistics_extension_ = NULL;
101 delete trigger_failure_extension_;
102 trigger_failure_extension_ = NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000103}
104
105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106void DeleteNativeSources(Object* maybe_array) {
107 if (maybe_array->IsFixedArray()) {
108 FixedArray* array = FixedArray::cast(maybe_array);
109 for (int i = 0; i < array->length(); i++) {
110 Object* natives_source = array->get(i);
111 if (!natives_source->IsUndefined()) {
112 const NativesExternalStringResource* resource =
113 reinterpret_cast<const NativesExternalStringResource*>(
114 ExternalOneByteString::cast(natives_source)->resource());
115 delete resource;
116 }
Leon Clarkee46be812010-01-19 14:06:41 +0000117 }
Leon Clarkee46be812010-01-19 14:06:41 +0000118 }
Leon Clarkee46be812010-01-19 14:06:41 +0000119}
120
121
Steve Blocka7e24c12009-10-30 11:49:00 +0000122void Bootstrapper::TearDown() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 DeleteNativeSources(Natives::GetSourceCache(isolate_->heap()));
124 DeleteNativeSources(ExperimentalNatives::GetSourceCache(isolate_->heap()));
125 DeleteNativeSources(ExtraNatives::GetSourceCache(isolate_->heap()));
126 DeleteNativeSources(
127 ExperimentalExtraNatives::GetSourceCache(isolate_->heap()));
Leon Clarkee46be812010-01-19 14:06:41 +0000128
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129 extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical
Steve Blocka7e24c12009-10-30 11:49:00 +0000130}
131
132
Steve Blocka7e24c12009-10-30 11:49:00 +0000133class Genesis BASE_EMBEDDED {
134 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135 Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
136 v8::Local<v8::ObjectTemplate> global_proxy_template,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100137 v8::ExtensionConfiguration* extensions,
138 GlobalContextType context_type);
Andrei Popescu31002712010-02-23 13:46:05 +0000139 ~Genesis() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000140
Ben Murdoch257744e2011-11-30 15:57:28 +0000141 Isolate* isolate() const { return isolate_; }
142 Factory* factory() const { return isolate_->factory(); }
143 Heap* heap() const { return isolate_->heap(); }
144
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 Handle<Context> result() { return result_; }
146
Steve Blocka7e24c12009-10-30 11:49:00 +0000147 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000148 Handle<Context> native_context() { return native_context_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000149
Andrei Popescu31002712010-02-23 13:46:05 +0000150 // Creates some basic objects. Used for creating a context from scratch.
151 void CreateRoots();
152 // Creates the empty function. Used for creating a context from scratch.
Ben Murdoch257744e2011-11-30 15:57:28 +0000153 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
Steve Block44f0eee2011-05-26 01:26:41 +0100154 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
156 Handle<JSFunction> GetStrictArgumentsPoisonFunction();
157 Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name);
Steve Block44f0eee2011-05-26 01:26:41 +0100158
159 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000160 void CreateIteratorMaps();
Ben Murdochda12d292016-06-02 14:46:10 +0100161 void CreateJSProxyMaps();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100162
163 // Make the "arguments" and "caller" properties throw a TypeError on access.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 void AddRestrictedFunctionProperties(Handle<Map> map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100165
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000166 // Creates the global objects using the global proxy and the template passed
167 // in through the API. We call this regardless of whether we are building a
Andrei Popescu31002712010-02-23 13:46:05 +0000168 // context from scratch or using a deserialized one from the partial snapshot
169 // but in the latter case we don't use the objects it produces directly, as
170 // we have to used the deserialized ones that are linked together with the
171 // rest of the context snapshot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172 Handle<JSGlobalObject> CreateNewGlobals(
173 v8::Local<v8::ObjectTemplate> global_proxy_template,
174 Handle<JSGlobalProxy> global_proxy);
Andrei Popescu31002712010-02-23 13:46:05 +0000175 // Hooks the given global proxy into the context. If the context was created
176 // by deserialization then this will unhook the global proxy that was
177 // deserialized, leaving the GC to pick it up.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000178 void HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
Andrei Popescu31002712010-02-23 13:46:05 +0000179 Handle<JSGlobalProxy> global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 // Similarly, we want to use the global that has been created by the templates
181 // passed through the API. The global from the snapshot is detached from the
182 // other objects in the snapshot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 void HookUpGlobalObject(Handle<JSGlobalObject> global_object);
184 // The native context has a ScriptContextTable that store declarative bindings
185 // made in script scopes. Add a "this" binding to that table pointing to the
186 // global proxy.
187 void InstallGlobalThisBinding();
Andrei Popescu31002712010-02-23 13:46:05 +0000188 // New context initialization. Used for creating a context from scratch.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189 void InitializeGlobal(Handle<JSGlobalObject> global_object,
190 Handle<JSFunction> empty_function,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100191 GlobalContextType context_type);
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000192 void InitializeExperimentalGlobal();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000193 // Depending on the situation, expose and/or get rid of the utils object.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100194 void ConfigureUtilsObject(GlobalContextType context_type);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400195
196#define DECLARE_FEATURE_INITIALIZATION(id, descr) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400197 void InitializeGlobal_##id();
198
199 HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
200 HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
201 HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202 DECLARE_FEATURE_INITIALIZATION(promise_extra, "")
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400203#undef DECLARE_FEATURE_INITIALIZATION
204
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000205 Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
206 const char* name);
207 Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208 const char* name,
209 ElementsKind elements_kind);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100210 bool InstallNatives(GlobalContextType context_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212 void InstallTypedArray(const char* name, ElementsKind elements_kind,
213 Handle<JSFunction>* fun);
Ben Murdoch257744e2011-11-30 15:57:28 +0000214 bool InstallExperimentalNatives();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000215 bool InstallExtraNatives();
216 bool InstallExperimentalExtraNatives();
217 bool InstallDebuggerNatives();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100218 void InstallBuiltinFunctionIds();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 void InstallExperimentalBuiltinFunctionIds();
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100220 void InitializeNormalizedMapCaches();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100221
222 enum ExtensionTraversalState {
223 UNVISITED, VISITED, INSTALLED
224 };
225
226 class ExtensionStates {
227 public:
228 ExtensionStates();
229 ExtensionTraversalState get_state(RegisteredExtension* extension);
230 void set_state(RegisteredExtension* extension,
231 ExtensionTraversalState state);
232 private:
233 HashMap map_;
234 DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
235 };
236
Andrei Popescu31002712010-02-23 13:46:05 +0000237 // Used both for deserialized and from-scratch contexts to add the extensions
238 // provided.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000239 static bool InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +0000240 v8::ExtensionConfiguration* extensions);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241 static bool InstallAutoExtensions(Isolate* isolate,
242 ExtensionStates* extension_states);
243 static bool InstallRequestedExtensions(Isolate* isolate,
244 v8::ExtensionConfiguration* extensions,
245 ExtensionStates* extension_states);
246 static bool InstallExtension(Isolate* isolate,
247 const char* name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100248 ExtensionStates* extension_states);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000249 static bool InstallExtension(Isolate* isolate,
250 v8::RegisteredExtension* current,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100251 ExtensionStates* extension_states);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000252 static bool InstallSpecialObjects(Handle<Context> native_context);
Steve Blocka7e24c12009-10-30 11:49:00 +0000253 bool ConfigureApiObject(Handle<JSObject> object,
254 Handle<ObjectTemplateInfo> object_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000255 bool ConfigureGlobalObjects(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000256 v8::Local<v8::ObjectTemplate> global_proxy_template);
Steve Blocka7e24c12009-10-30 11:49:00 +0000257
258 // Migrates all properties from the 'from' object to the 'to'
259 // object and overrides the prototype in 'to' with the one from
260 // 'from'.
261 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
262 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
263 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
264
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265 enum FunctionMode {
266 // With prototype.
267 FUNCTION_WITH_WRITEABLE_PROTOTYPE,
268 FUNCTION_WITH_READONLY_PROTOTYPE,
269 // Without prototype.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270 FUNCTION_WITHOUT_PROTOTYPE
Steve Block6ded16b2010-05-10 14:33:55 +0100271 };
Steve Block44f0eee2011-05-26 01:26:41 +0100272
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000273 static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
274 return (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
275 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE);
276 }
Steve Block44f0eee2011-05-26 01:26:41 +0100277
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000278 Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279
280 void SetFunctionInstanceDescriptor(Handle<Map> map,
281 FunctionMode function_mode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000282 void MakeFunctionInstancePrototypeWritable();
283
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000284 Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode,
285 Handle<JSFunction> empty_function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000286
Steve Block44f0eee2011-05-26 01:26:41 +0100287
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000288 void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
289 FunctionMode function_mode);
Steve Block44f0eee2011-05-26 01:26:41 +0100290
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000291 static bool CallUtilsFunction(Isolate* isolate, const char* name);
292
293 static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
Steve Blocka7e24c12009-10-30 11:49:00 +0000294
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000295 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000296 Handle<Context> result_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000297 Handle<Context> native_context_;
Steve Block44f0eee2011-05-26 01:26:41 +0100298
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000299 // Function maps. Function maps are created initially with a read only
300 // prototype for the processing of JS builtins. Later the function maps are
301 // replaced in order to make prototype writable. These are the final, writable
302 // prototype, maps.
303 Handle<Map> sloppy_function_map_writable_prototype_;
304 Handle<Map> strict_function_map_writable_prototype_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000305 Handle<JSFunction> strict_poison_function_;
306 Handle<JSFunction> restricted_function_properties_thrower_;
Steve Block44f0eee2011-05-26 01:26:41 +0100307
Andrei Popescu31002712010-02-23 13:46:05 +0000308 BootstrapperActive active_;
309 friend class Bootstrapper;
Steve Blocka7e24c12009-10-30 11:49:00 +0000310};
311
Steve Blocka7e24c12009-10-30 11:49:00 +0000312
313void Bootstrapper::Iterate(ObjectVisitor* v) {
Steve Block44f0eee2011-05-26 01:26:41 +0100314 extensions_cache_.Iterate(v);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100315 v->Synchronize(VisitorSynchronization::kExtensions);
Steve Blocka7e24c12009-10-30 11:49:00 +0000316}
317
Steve Blocka7e24c12009-10-30 11:49:00 +0000318Handle<Context> Bootstrapper::CreateEnvironment(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000319 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000320 v8::Local<v8::ObjectTemplate> global_proxy_template,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100321 v8::ExtensionConfiguration* extensions, GlobalContextType context_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000322 HandleScope scope(isolate_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323 Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template,
324 extensions, context_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000325 Handle<Context> env = genesis.result();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326 if (env.is_null() ||
327 (context_type != THIN_CONTEXT && !InstallExtensions(env, extensions))) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000328 return Handle<Context>();
Andrei Popescu31002712010-02-23 13:46:05 +0000329 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000330 return scope.CloseAndEscape(env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000331}
332
333
334static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
335 // object.__proto__ = proto;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000336 Handle<Map> old_map = Handle<Map>(object->map());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400337 Handle<Map> new_map = Map::Copy(old_map, "SetObjectPrototype");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000338 Map::SetPrototype(new_map, proto, FAST_PROTOTYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000339 JSObject::MigrateToMap(object, new_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000340}
341
342
343void Bootstrapper::DetachGlobal(Handle<Context> env) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000344 env->GetIsolate()->counters()->errors_thrown_per_context()->AddSample(
345 env->GetErrorsThrown());
346
Ben Murdoch257744e2011-11-30 15:57:28 +0000347 Factory* factory = env->GetIsolate()->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000348 Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
349 global_proxy->set_native_context(*factory->null_value());
350 SetObjectPrototype(global_proxy, factory->null_value());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000351 global_proxy->map()->SetConstructor(*factory->null_value());
352 if (FLAG_track_detached_contexts) {
353 env->GetIsolate()->AddDetachedContext(env);
354 }
Andrei Popescu74b3c142010-03-29 12:03:09 +0100355}
356
357
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000358namespace {
359
360void InstallFunction(Handle<JSObject> target, Handle<Name> property_name,
361 Handle<JSFunction> function, Handle<String> function_name,
362 PropertyAttributes attributes = DONT_ENUM) {
363 JSObject::AddProperty(target, property_name, function, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000364 if (target->IsJSGlobalObject()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000365 function->shared()->set_instance_class_name(*function_name);
Steve Blocka7e24c12009-10-30 11:49:00 +0000366 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100367 function->shared()->set_native(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368}
369
370
371static void InstallFunction(Handle<JSObject> target,
372 Handle<JSFunction> function, Handle<Name> name,
373 PropertyAttributes attributes = DONT_ENUM) {
374 Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
375 InstallFunction(target, name, function, name_string, attributes);
376}
377
378
379static Handle<JSFunction> CreateFunction(Isolate* isolate, Handle<String> name,
380 InstanceType type, int instance_size,
381 MaybeHandle<JSObject> maybe_prototype,
382 Builtins::Name call,
383 bool strict_function_map = false) {
384 Factory* factory = isolate->factory();
385 Handle<Code> call_code(isolate->builtins()->builtin(call));
386 Handle<JSObject> prototype;
387 static const bool kReadOnlyPrototype = false;
388 static const bool kInstallConstructor = false;
389 return maybe_prototype.ToHandle(&prototype)
390 ? factory->NewFunction(name, call_code, prototype, type,
391 instance_size, kReadOnlyPrototype,
392 kInstallConstructor, strict_function_map)
393 : factory->NewFunctionWithoutPrototype(name, call_code,
394 strict_function_map);
395}
396
397
398Handle<JSFunction> InstallFunction(Handle<JSObject> target, Handle<Name> name,
399 InstanceType type, int instance_size,
400 MaybeHandle<JSObject> maybe_prototype,
401 Builtins::Name call,
402 PropertyAttributes attributes,
403 bool strict_function_map = false) {
404 Handle<String> name_string = Name::ToFunctionName(name).ToHandleChecked();
405 Handle<JSFunction> function =
406 CreateFunction(target->GetIsolate(), name_string, type, instance_size,
407 maybe_prototype, call, strict_function_map);
408 InstallFunction(target, name, function, name_string, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000409 return function;
410}
411
412
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413Handle<JSFunction> InstallFunction(Handle<JSObject> target, const char* name,
414 InstanceType type, int instance_size,
415 MaybeHandle<JSObject> maybe_prototype,
416 Builtins::Name call,
417 bool strict_function_map = false) {
418 Factory* const factory = target->GetIsolate()->factory();
419 PropertyAttributes attributes = DONT_ENUM;
420 return InstallFunction(target, factory->InternalizeUtf8String(name), type,
421 instance_size, maybe_prototype, call, attributes,
422 strict_function_map);
423}
424
425} // namespace
426
427
428void Genesis::SetFunctionInstanceDescriptor(Handle<Map> map,
429 FunctionMode function_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000430 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
431 Map::EnsureDescriptorSlack(map, size);
432
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000433 PropertyAttributes ro_attribs =
434 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
435 PropertyAttributes roc_attribs =
436 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100437
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000438 Handle<AccessorInfo> length =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439 Accessors::FunctionLengthInfo(isolate(), roc_attribs);
Steve Block44f0eee2011-05-26 01:26:41 +0100440 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
442 length, roc_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000443 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100444 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000445 Handle<AccessorInfo> name =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000446 Accessors::FunctionNameInfo(isolate(), ro_attribs);
Steve Block44f0eee2011-05-26 01:26:41 +0100447 { // Add name.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000448 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
449 roc_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000450 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100451 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000452 Handle<AccessorInfo> args =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 Accessors::FunctionArgumentsInfo(isolate(), ro_attribs);
Steve Block44f0eee2011-05-26 01:26:41 +0100454 { // Add arguments.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000455 AccessorConstantDescriptor d(Handle<Name>(Name::cast(args->name())), args,
456 ro_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000457 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100458 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000459 Handle<AccessorInfo> caller =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460 Accessors::FunctionCallerInfo(isolate(), ro_attribs);
Steve Block44f0eee2011-05-26 01:26:41 +0100461 { // Add caller.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000462 AccessorConstantDescriptor d(Handle<Name>(Name::cast(caller->name())),
463 caller, ro_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000464 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100465 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000466 if (IsFunctionModeWithPrototype(function_mode)) {
467 if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000468 ro_attribs = static_cast<PropertyAttributes>(ro_attribs & ~READ_ONLY);
Steve Block44f0eee2011-05-26 01:26:41 +0100469 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000470 Handle<AccessorInfo> prototype =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000471 Accessors::FunctionPrototypeInfo(isolate(), ro_attribs);
472 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
473 prototype, ro_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000474 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100475 }
Steve Block44f0eee2011-05-26 01:26:41 +0100476}
Steve Blocka7e24c12009-10-30 11:49:00 +0000477
Steve Blocka7e24c12009-10-30 11:49:00 +0000478
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000479Handle<Map> Genesis::CreateSloppyFunctionMap(FunctionMode function_mode) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000480 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000481 SetFunctionInstanceDescriptor(map, function_mode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100482 map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000483 map->set_is_callable();
Steve Block44f0eee2011-05-26 01:26:41 +0100484 return map;
Steve Blocka7e24c12009-10-30 11:49:00 +0000485}
486
487
Ben Murdoch257744e2011-11-30 15:57:28 +0000488Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100489 // Allocate the map for function instances. Maps are allocated first and their
490 // prototypes patched later, once empty function is created.
491
Steve Block6ded16b2010-05-10 14:33:55 +0100492 // Functions with this map will not have a 'prototype' property, and
493 // can not be used as constructors.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100494 Handle<Map> function_without_prototype_map =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000495 CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000496 native_context()->set_sloppy_function_without_prototype_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100497 *function_without_prototype_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000498
Steve Block44f0eee2011-05-26 01:26:41 +0100499 // Allocate the function map. This map is temporary, used only for processing
500 // of builtins.
501 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000502 Handle<Map> function_map =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000503 CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000504 native_context()->set_sloppy_function_map(*function_map);
505 native_context()->set_sloppy_function_with_readonly_prototype_map(
506 *function_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000507
Steve Block44f0eee2011-05-26 01:26:41 +0100508 // The final map for functions. Writeable prototype.
509 // This map is installed in MakeFunctionInstancePrototypeWritable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000510 sloppy_function_map_writable_prototype_ =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000511 CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
Steve Block44f0eee2011-05-26 01:26:41 +0100512 Factory* factory = isolate->factory();
Steve Block44f0eee2011-05-26 01:26:41 +0100513
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000514 Handle<String> object_name = factory->Object_string();
Steve Blocka7e24c12009-10-30 11:49:00 +0000515
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400516 Handle<JSObject> object_function_prototype;
517
Steve Blocka7e24c12009-10-30 11:49:00 +0000518 { // --- O b j e c t ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000519 Handle<JSFunction> object_fun = factory->NewFunction(object_name);
520 int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
521 int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
Steve Blocka7e24c12009-10-30 11:49:00 +0000522 Handle<Map> object_function_map =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000523 factory->NewMap(JS_OBJECT_TYPE, instance_size);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000524 object_function_map->SetInObjectProperties(unused);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000525 JSFunction::SetInitialMap(object_fun, object_function_map,
526 isolate->factory()->null_value());
527 object_function_map->set_unused_property_fields(unused);
Steve Blocka7e24c12009-10-30 11:49:00 +0000528
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000529 native_context()->set_object_function(*object_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +0000530
531 // Allocate a new prototype for the object function.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400532 object_function_prototype =
533 factory->NewJSObject(isolate->object_function(), TENURED);
534 Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
535 "EmptyObjectPrototype");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000536 map->set_is_prototype_map(true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400537 object_function_prototype->set_map(*map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000538
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400539 native_context()->set_initial_object_prototype(*object_function_prototype);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000540 // For bootstrapping set the array prototype to be the same as the object
541 // prototype, otherwise the missing initial_array_prototype will cause
542 // assertions during startup.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400543 native_context()->set_initial_array_prototype(*object_function_prototype);
544 Accessors::FunctionSetPrototype(object_fun, object_function_prototype)
545 .Assert();
Steve Blocka7e24c12009-10-30 11:49:00 +0000546 }
547
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000548 // Allocate the empty function as the prototype for function - ES6 19.2.3
549 Handle<Code> code(isolate->builtins()->EmptyFunction());
550 Handle<JSFunction> empty_function =
551 factory->NewFunctionWithoutPrototype(factory->empty_string(), code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000552
553 // Allocate the function map first and then patch the prototype later
554 Handle<Map> empty_function_map =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000555 CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000556 DCHECK(!empty_function_map->is_dictionary_map());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000557 Map::SetPrototype(empty_function_map, object_function_prototype);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000558 empty_function_map->set_is_prototype_map(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000559
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000560 empty_function->set_map(*empty_function_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000561
Andrei Popescu31002712010-02-23 13:46:05 +0000562 // --- E m p t y ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000563 Handle<String> source = factory->NewStringFromStaticChars("() {}");
Steve Block44f0eee2011-05-26 01:26:41 +0100564 Handle<Script> script = factory->NewScript(source);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565 script->set_type(Script::TYPE_NATIVE);
Andrei Popescu31002712010-02-23 13:46:05 +0000566 empty_function->shared()->set_start_position(0);
567 empty_function->shared()->set_end_position(source->length());
568 empty_function->shared()->DontAdaptArguments();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569 SharedFunctionInfo::SetScript(handle(empty_function->shared()), script);
Steve Block44f0eee2011-05-26 01:26:41 +0100570
571 // Set prototypes for the function maps.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000572 Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),
573 isolate);
574 Handle<Map> sloppy_function_without_prototype_map(
575 native_context()->sloppy_function_without_prototype_map(), isolate);
576 Map::SetPrototype(sloppy_function_map, empty_function);
577 Map::SetPrototype(sloppy_function_without_prototype_map, empty_function);
578 Map::SetPrototype(sloppy_function_map_writable_prototype_, empty_function);
579
580 // ES6 draft 03-17-2015, section 8.2.2 step 12
581 AddRestrictedFunctionProperties(empty_function_map);
582
Andrei Popescu31002712010-02-23 13:46:05 +0000583 return empty_function;
584}
585
586
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000587void Genesis::SetStrictFunctionInstanceDescriptor(Handle<Map> map,
588 FunctionMode function_mode) {
589 int size = IsFunctionModeWithPrototype(function_mode) ? 3 : 2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000590 Map::EnsureDescriptorSlack(map, size);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000591
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000592 PropertyAttributes rw_attribs =
593 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
594 PropertyAttributes ro_attribs =
595 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000596 PropertyAttributes roc_attribs =
597 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100598
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000599 DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
600 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE ||
601 function_mode == FUNCTION_WITHOUT_PROTOTYPE);
602 { // Add length.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000603 Handle<AccessorInfo> length =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000604 Accessors::FunctionLengthInfo(isolate(), roc_attribs);
605 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
606 length, roc_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000607 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100608 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100609 { // Add name.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000610 Handle<AccessorInfo> name =
611 Accessors::FunctionNameInfo(isolate(), roc_attribs);
612 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
613 roc_attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000614 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100615 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000616 if (IsFunctionModeWithPrototype(function_mode)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100617 // Add prototype.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000618 PropertyAttributes attribs =
619 function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs
620 : ro_attribs;
621 Handle<AccessorInfo> prototype =
622 Accessors::FunctionPrototypeInfo(isolate(), attribs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000623 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
624 prototype, attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000625 map->AppendDescriptor(&d);
Steve Block44f0eee2011-05-26 01:26:41 +0100626 }
Steve Block44f0eee2011-05-26 01:26:41 +0100627}
628
629
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000630// Creates the %ThrowTypeError% function.
631Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic(
632 Builtins::Name builtin_name) {
633 Handle<String> name =
634 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("ThrowTypeError"));
635 Handle<Code> code(isolate()->builtins()->builtin(builtin_name));
636 Handle<JSFunction> function =
637 factory()->NewFunctionWithoutPrototype(name, code);
638 function->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000639
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000640 // %ThrowTypeError% must not have a name property.
641 if (JSReceiver::DeleteProperty(function, factory()->name_string())
642 .IsNothing()) {
643 DCHECK(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000644 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000645
646 // length needs to be non configurable.
647 Handle<Object> value(Smi::FromInt(function->shared()->length()), isolate());
648 JSObject::SetOwnPropertyIgnoreAttributes(
649 function, factory()->length_string(), value,
650 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY))
651 .Assert();
652
653 if (JSObject::PreventExtensions(function, Object::THROW_ON_ERROR)
654 .IsNothing()) {
655 DCHECK(false);
656 }
657
658 return function;
659}
660
661
662// ECMAScript 5th Edition, 13.2.3
663Handle<JSFunction> Genesis::GetRestrictedFunctionPropertiesThrower() {
664 if (restricted_function_properties_thrower_.is_null()) {
665 restricted_function_properties_thrower_ = GetThrowTypeErrorIntrinsic(
666 Builtins::kRestrictedFunctionPropertiesThrower);
667 }
668 return restricted_function_properties_thrower_;
669}
670
671
672Handle<JSFunction> Genesis::GetStrictArgumentsPoisonFunction() {
673 if (strict_poison_function_.is_null()) {
674 strict_poison_function_ = GetThrowTypeErrorIntrinsic(
675 Builtins::kRestrictedStrictArgumentsPropertiesThrower);
676 }
677 return strict_poison_function_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000678}
679
680
681Handle<Map> Genesis::CreateStrictFunctionMap(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000682 FunctionMode function_mode, Handle<JSFunction> empty_function) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000683 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000684 SetStrictFunctionInstanceDescriptor(map, function_mode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100685 map->set_is_constructor(IsFunctionModeWithPrototype(function_mode));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000686 map->set_is_callable();
687 Map::SetPrototype(map, empty_function);
688 return map;
689}
690
691
Steve Block44f0eee2011-05-26 01:26:41 +0100692void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
Steve Block44f0eee2011-05-26 01:26:41 +0100693 // Allocate map for the prototype-less strict mode instances.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000694 Handle<Map> strict_function_without_prototype_map =
695 CreateStrictFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty);
696 native_context()->set_strict_function_without_prototype_map(
697 *strict_function_without_prototype_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100698
699 // Allocate map for the strict mode functions. This map is temporary, used
700 // only for processing of builtins.
701 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000702 Handle<Map> strict_function_map =
703 CreateStrictFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty);
704 native_context()->set_strict_function_map(*strict_function_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100705
706 // The final map for the strict mode functions. Writeable prototype.
707 // This map is installed in MakeFunctionInstancePrototypeWritable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000708 strict_function_map_writable_prototype_ =
709 CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100710}
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100711
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100712
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000713void Genesis::CreateIteratorMaps() {
714 // Create iterator-related meta-objects.
715 Handle<JSObject> iterator_prototype =
716 factory()->NewJSObject(isolate()->object_function(), TENURED);
717 Handle<JSObject> generator_object_prototype =
718 factory()->NewJSObject(isolate()->object_function(), TENURED);
719 Handle<JSObject> generator_function_prototype =
720 factory()->NewJSObject(isolate()->object_function(), TENURED);
721 SetObjectPrototype(generator_object_prototype, iterator_prototype);
722
723 JSObject::AddProperty(generator_function_prototype,
724 factory()->InternalizeUtf8String("prototype"),
725 generator_object_prototype,
726 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
727
728 // Create maps for generator functions and their prototypes. Store those
729 // maps in the native context. The "prototype" property descriptor is
730 // writable, non-enumerable, and non-configurable (as per ES6 draft
731 // 04-14-15, section 25.2.4.3).
732 Handle<Map> strict_function_map(strict_function_map_writable_prototype_);
733 // Generator functions do not have "caller" or "arguments" accessors.
734 Handle<Map> sloppy_generator_function_map =
735 Map::Copy(strict_function_map, "SloppyGeneratorFunction");
Ben Murdoch097c5b22016-05-18 11:27:45 +0100736 sloppy_generator_function_map->set_is_constructor(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000737 Map::SetPrototype(sloppy_generator_function_map,
738 generator_function_prototype);
739 native_context()->set_sloppy_generator_function_map(
740 *sloppy_generator_function_map);
741
742 Handle<Map> strict_generator_function_map =
743 Map::Copy(strict_function_map, "StrictGeneratorFunction");
Ben Murdoch097c5b22016-05-18 11:27:45 +0100744 strict_generator_function_map->set_is_constructor(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000745 Map::SetPrototype(strict_generator_function_map,
746 generator_function_prototype);
747 native_context()->set_strict_generator_function_map(
748 *strict_generator_function_map);
749
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000750 Handle<JSFunction> object_function(native_context()->object_function());
751 Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
752 Map::SetPrototype(generator_object_prototype_map, generator_object_prototype);
753 native_context()->set_generator_object_prototype_map(
754 *generator_object_prototype_map);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100755}
756
Ben Murdochda12d292016-06-02 14:46:10 +0100757void Genesis::CreateJSProxyMaps() {
758 // Allocate the different maps for all Proxy types.
759 // Next to the default proxy, we need maps indicating callable and
760 // constructable proxies.
761 Handle<Map> proxy_function_map =
762 Map::Copy(isolate()->sloppy_function_without_prototype_map(), "Proxy");
763 proxy_function_map->set_is_constructor(true);
764 native_context()->set_proxy_function_map(*proxy_function_map);
765
766 Handle<Map> proxy_map =
767 factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, FAST_ELEMENTS);
768 proxy_map->set_dictionary_map(true);
769 native_context()->set_proxy_map(*proxy_map);
770
771 Handle<Map> proxy_callable_map = Map::Copy(proxy_map, "callable Proxy");
772 proxy_callable_map->set_is_callable();
773 native_context()->set_proxy_callable_map(*proxy_callable_map);
774 proxy_callable_map->SetConstructor(native_context()->function_function());
775
776 Handle<Map> proxy_constructor_map =
777 Map::Copy(proxy_callable_map, "constructor Proxy");
778 proxy_constructor_map->set_is_constructor(true);
779 native_context()->set_proxy_constructor_map(*proxy_constructor_map);
780}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100781
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000782static void ReplaceAccessors(Handle<Map> map,
783 Handle<String> name,
784 PropertyAttributes attributes,
785 Handle<AccessorPair> accessor_pair) {
786 DescriptorArray* descriptors = map->instance_descriptors();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100787 int idx = descriptors->SearchWithCache(map->GetIsolate(), *name, *map);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000788 AccessorConstantDescriptor descriptor(name, accessor_pair, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000789 descriptors->Replace(idx, &descriptor);
Steve Block44f0eee2011-05-26 01:26:41 +0100790}
791
792
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000793void Genesis::AddRestrictedFunctionProperties(Handle<Map> map) {
794 PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
795 Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower();
796 Handle<AccessorPair> accessors = factory()->NewAccessorPair();
797 accessors->set_getter(*thrower);
798 accessors->set_setter(*thrower);
799
800 ReplaceAccessors(map, factory()->arguments_string(), rw_attribs, accessors);
801 ReplaceAccessors(map, factory()->caller_string(), rw_attribs, accessors);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000802}
803
804
805static void AddToWeakNativeContextList(Context* context) {
806 DCHECK(context->IsNativeContext());
Ben Murdoch257744e2011-11-30 15:57:28 +0000807 Heap* heap = context->GetIsolate()->heap();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100808#ifdef DEBUG
809 { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000810 DCHECK(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100811 // Check that context is not in the list yet.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000812 for (Object* current = heap->native_contexts_list();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100813 !current->IsUndefined();
814 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000815 DCHECK(current != context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100816 }
817 }
818#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000819 context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list(),
820 UPDATE_WEAK_WRITE_BARRIER);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000821 heap->set_native_contexts_list(context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100822}
823
824
Andrei Popescu31002712010-02-23 13:46:05 +0000825void Genesis::CreateRoots() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000826 // Allocate the native context FixedArray first and then patch the
Andrei Popescu31002712010-02-23 13:46:05 +0000827 // closure and extension object later (we need the empty function
828 // and the global object, but in order to create those, we need the
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000829 // native context).
830 native_context_ = factory()->NewNativeContext();
831 AddToWeakNativeContextList(*native_context());
832 isolate()->set_context(*native_context());
Andrei Popescu31002712010-02-23 13:46:05 +0000833
834 // Allocate the message listeners object.
835 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000836 v8::NeanderArray listeners(isolate());
837 native_context()->set_message_listeners(*listeners.value());
Andrei Popescu31002712010-02-23 13:46:05 +0000838 }
839}
840
841
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000842void Genesis::InstallGlobalThisBinding() {
843 Handle<ScriptContextTable> script_contexts(
844 native_context()->script_context_table());
845 Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate());
846 Handle<JSFunction> closure(native_context()->closure());
847 Handle<Context> context = factory()->NewScriptContext(closure, scope_info);
848
849 // Go ahead and hook it up while we're at it.
850 int slot = scope_info->ReceiverContextSlotIndex();
851 DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS);
852 context->set(slot, native_context()->global_proxy());
853
854 Handle<ScriptContextTable> new_script_contexts =
855 ScriptContextTable::Extend(script_contexts, context);
856 native_context()->set_script_context_table(*new_script_contexts);
857}
858
859
860Handle<JSGlobalObject> Genesis::CreateNewGlobals(
861 v8::Local<v8::ObjectTemplate> global_proxy_template,
862 Handle<JSGlobalProxy> global_proxy) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000863 // The argument global_proxy_template aka data is an ObjectTemplateInfo.
Andrei Popescu31002712010-02-23 13:46:05 +0000864 // It has a constructor pointer that points at global_constructor which is a
865 // FunctionTemplateInfo.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000866 // The global_proxy_constructor is used to (re)initialize the
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867 // global_proxy. The global_proxy_constructor also has a prototype_template
868 // pointer that points at js_global_object_template which is an
869 // ObjectTemplateInfo.
Andrei Popescu31002712010-02-23 13:46:05 +0000870 // That in turn has a constructor pointer that points at
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000871 // js_global_object_constructor which is a FunctionTemplateInfo.
872 // js_global_object_constructor is used to make js_global_object_function
873 // js_global_object_function is used to make the new global_object.
Andrei Popescu31002712010-02-23 13:46:05 +0000874 //
875 // --- G l o b a l ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000876 // Step 1: Create a fresh JSGlobalObject.
877 Handle<JSFunction> js_global_object_function;
878 Handle<ObjectTemplateInfo> js_global_object_template;
879 if (!global_proxy_template.IsEmpty()) {
880 // Get prototype template of the global_proxy_template.
Andrei Popescu31002712010-02-23 13:46:05 +0000881 Handle<ObjectTemplateInfo> data =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000882 v8::Utils::OpenHandle(*global_proxy_template);
Andrei Popescu31002712010-02-23 13:46:05 +0000883 Handle<FunctionTemplateInfo> global_constructor =
884 Handle<FunctionTemplateInfo>(
885 FunctionTemplateInfo::cast(data->constructor()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000886 Handle<Object> proto_template(global_constructor->prototype_template(),
887 isolate());
Andrei Popescu31002712010-02-23 13:46:05 +0000888 if (!proto_template->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000889 js_global_object_template =
Andrei Popescu31002712010-02-23 13:46:05 +0000890 Handle<ObjectTemplateInfo>::cast(proto_template);
891 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000892 }
893
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000894 if (js_global_object_template.is_null()) {
895 Handle<String> name = Handle<String>(heap()->empty_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000896 Handle<Code> code = isolate()->builtins()->Illegal();
Andrei Popescu31002712010-02-23 13:46:05 +0000897 Handle<JSObject> prototype =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000898 factory()->NewFunctionPrototype(isolate()->object_function());
899 js_global_object_function = factory()->NewFunction(
900 name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
901#ifdef DEBUG
902 LookupIterator it(prototype, factory()->constructor_string(),
903 LookupIterator::OWN_SKIP_INTERCEPTOR);
Ben Murdochda12d292016-06-02 14:46:10 +0100904 Handle<Object> value = Object::GetProperty(&it).ToHandleChecked();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000905 DCHECK(it.IsFound());
906 DCHECK_EQ(*isolate()->object_function(), *value);
907#endif
Andrei Popescu31002712010-02-23 13:46:05 +0000908 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000909 Handle<FunctionTemplateInfo> js_global_object_constructor(
910 FunctionTemplateInfo::cast(js_global_object_template->constructor()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000911 js_global_object_function = ApiNatives::CreateApiFunction(
912 isolate(), js_global_object_constructor, factory()->the_hole_value(),
913 ApiNatives::GlobalObjectType);
Steve Blocka7e24c12009-10-30 11:49:00 +0000914 }
915
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000916 js_global_object_function->initial_map()->set_is_prototype_map(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000917 js_global_object_function->initial_map()->set_dictionary_map(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000918 Handle<JSGlobalObject> global_object =
919 factory()->NewJSGlobalObject(js_global_object_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000920
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000921 // Step 2: (re)initialize the global proxy object.
Andrei Popescu31002712010-02-23 13:46:05 +0000922 Handle<JSFunction> global_proxy_function;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000923 if (global_proxy_template.IsEmpty()) {
924 Handle<String> name = Handle<String>(heap()->empty_string());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000925 Handle<Code> code = isolate()->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000926 global_proxy_function = factory()->NewFunction(
927 name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
Andrei Popescu31002712010-02-23 13:46:05 +0000928 } else {
929 Handle<ObjectTemplateInfo> data =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000930 v8::Utils::OpenHandle(*global_proxy_template);
Andrei Popescu31002712010-02-23 13:46:05 +0000931 Handle<FunctionTemplateInfo> global_constructor(
932 FunctionTemplateInfo::cast(data->constructor()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000933 global_proxy_function = ApiNatives::CreateApiFunction(
934 isolate(), global_constructor, factory()->the_hole_value(),
935 ApiNatives::GlobalProxyType);
Andrei Popescu31002712010-02-23 13:46:05 +0000936 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000937 Handle<String> global_name = factory()->global_string();
Andrei Popescu31002712010-02-23 13:46:05 +0000938 global_proxy_function->shared()->set_instance_class_name(*global_name);
939 global_proxy_function->initial_map()->set_is_access_check_needed(true);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100940 global_proxy_function->initial_map()->set_has_hidden_prototype(true);
Andrei Popescu31002712010-02-23 13:46:05 +0000941
942 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
943 // Return the global proxy.
944
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000945 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
946 return global_object;
Andrei Popescu31002712010-02-23 13:46:05 +0000947}
948
949
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950void Genesis::HookUpGlobalProxy(Handle<JSGlobalObject> global_object,
Andrei Popescu31002712010-02-23 13:46:05 +0000951 Handle<JSGlobalProxy> global_proxy) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000952 // Set the native context for the global object.
953 global_object->set_native_context(*native_context());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000954 global_object->set_global_proxy(*global_proxy);
955 global_proxy->set_native_context(*native_context());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000956 // If we deserialized the context, the global proxy is already
957 // correctly set up. Otherwise it's undefined.
958 DCHECK(native_context()->get(Context::GLOBAL_PROXY_INDEX)->IsUndefined() ||
959 native_context()->global_proxy() == *global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000960 native_context()->set_global_proxy(*global_proxy);
Andrei Popescu31002712010-02-23 13:46:05 +0000961}
962
963
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000964void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) {
965 Handle<JSGlobalObject> global_object_from_snapshot(
966 JSGlobalObject::cast(native_context()->extension()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000967 native_context()->set_extension(*global_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000968 native_context()->set_security_token(*global_object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000969
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000970 TransferNamedProperties(global_object_from_snapshot, global_object);
971 TransferIndexedProperties(global_object_from_snapshot, global_object);
Andrei Popescu402d9372010-02-26 13:31:12 +0000972}
973
974
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000975static Handle<JSFunction> SimpleCreateFunction(Isolate* isolate,
976 Handle<String> name,
977 Builtins::Name call, int len,
978 bool adapt) {
979 Handle<JSFunction> fun =
980 CreateFunction(isolate, name, JS_OBJECT_TYPE, JSObject::kHeaderSize,
981 MaybeHandle<JSObject>(), call);
982 if (adapt) {
983 fun->shared()->set_internal_formal_parameter_count(len);
984 } else {
985 fun->shared()->DontAdaptArguments();
986 }
987 fun->shared()->set_length(len);
988 return fun;
989}
990
991
992static Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
993 Handle<String> name,
994 Builtins::Name call, int len,
995 bool adapt) {
996 Handle<JSFunction> fun =
997 SimpleCreateFunction(base->GetIsolate(), name, call, len, adapt);
998 InstallFunction(base, fun, name, DONT_ENUM);
999 return fun;
1000}
1001
1002
1003static Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
1004 const char* name,
1005 Builtins::Name call, int len,
1006 bool adapt) {
1007 Factory* const factory = base->GetIsolate()->factory();
1008 return SimpleInstallFunction(base, factory->InternalizeUtf8String(name), call,
1009 len, adapt);
1010}
1011
1012
1013static void InstallWithIntrinsicDefaultProto(Isolate* isolate,
1014 Handle<JSFunction> function,
1015 int context_index) {
1016 Handle<Smi> index(Smi::FromInt(context_index), isolate);
1017 JSObject::AddProperty(
1018 function, isolate->factory()->native_context_index_symbol(), index, NONE);
1019 isolate->native_context()->set(context_index, *function);
1020}
1021
1022
Andrei Popescu402d9372010-02-26 13:31:12 +00001023// This is only called if we are not using snapshots. The equivalent
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001024// work in the snapshot case is done in HookUpGlobalObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001025void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1026 Handle<JSFunction> empty_function,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001027 GlobalContextType context_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001028 // --- N a t i v e C o n t e x t ---
Andrei Popescu31002712010-02-23 13:46:05 +00001029 // Use the empty function as closure (no scope info).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001030 native_context()->set_closure(*empty_function);
1031 native_context()->set_previous(NULL);
Andrei Popescu31002712010-02-23 13:46:05 +00001032 // Set extension and global object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001033 native_context()->set_extension(*global_object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001034 // Security setup: Set the security token of the native context to the global
1035 // object. This makes the security check between two different contexts fail
1036 // by default even in case of global object reinitialization.
1037 native_context()->set_security_token(*global_object);
Andrei Popescu31002712010-02-23 13:46:05 +00001038
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001039 Isolate* isolate = global_object->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001040 Factory* factory = isolate->factory();
Steve Block44f0eee2011-05-26 01:26:41 +01001041
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001042 Handle<ScriptContextTable> script_context_table =
1043 factory->NewScriptContextTable();
1044 native_context()->set_script_context_table(*script_context_table);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001045 InstallGlobalThisBinding();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001046
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001047 { // --- O b j e c t ---
1048 Handle<String> object_name = factory->Object_string();
1049 Handle<JSFunction> object_function = isolate->object_function();
1050 JSObject::AddProperty(global_object, object_name, object_function,
1051 DONT_ENUM);
1052 SimpleInstallFunction(object_function, factory->assign_string(),
1053 Builtins::kObjectAssign, 2, false);
1054 SimpleInstallFunction(object_function, factory->create_string(),
1055 Builtins::kObjectCreate, 2, false);
1056 Handle<JSFunction> object_freeze = SimpleInstallFunction(
1057 object_function, "freeze", Builtins::kObjectFreeze, 1, false);
1058 native_context()->set_object_freeze(*object_freeze);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001059 SimpleInstallFunction(object_function, "getOwnPropertyDescriptor",
1060 Builtins::kObjectGetOwnPropertyDescriptor, 2, false);
1061 SimpleInstallFunction(object_function, "getOwnPropertyNames",
1062 Builtins::kObjectGetOwnPropertyNames, 1, false);
1063 SimpleInstallFunction(object_function, "getOwnPropertySymbols",
1064 Builtins::kObjectGetOwnPropertySymbols, 1, false);
1065 SimpleInstallFunction(object_function, "is", Builtins::kObjectIs, 2, true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001066 Handle<JSFunction> object_is_extensible =
1067 SimpleInstallFunction(object_function, "isExtensible",
1068 Builtins::kObjectIsExtensible, 1, false);
1069 native_context()->set_object_is_extensible(*object_is_extensible);
1070 Handle<JSFunction> object_is_frozen = SimpleInstallFunction(
1071 object_function, "isFrozen", Builtins::kObjectIsFrozen, 1, false);
1072 native_context()->set_object_is_frozen(*object_is_frozen);
1073 Handle<JSFunction> object_is_sealed = SimpleInstallFunction(
1074 object_function, "isSealed", Builtins::kObjectIsSealed, 1, false);
1075 native_context()->set_object_is_sealed(*object_is_sealed);
1076 Handle<JSFunction> object_keys = SimpleInstallFunction(
1077 object_function, "keys", Builtins::kObjectKeys, 1, false);
1078 native_context()->set_object_keys(*object_keys);
1079 SimpleInstallFunction(object_function, "preventExtensions",
1080 Builtins::kObjectPreventExtensions, 1, false);
1081 SimpleInstallFunction(object_function, "seal", Builtins::kObjectSeal, 1,
1082 false);
Ben Murdochda12d292016-06-02 14:46:10 +01001083
1084 SimpleInstallFunction(isolate->initial_object_prototype(), "hasOwnProperty",
1085 Builtins::kObjectHasOwnProperty, 1, true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001086 }
Andrei Popescu31002712010-02-23 13:46:05 +00001087
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001088 Handle<JSObject> global(native_context()->global_object());
Steve Blocka7e24c12009-10-30 11:49:00 +00001089
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001090 { // --- F u n c t i o n ---
1091 Handle<JSFunction> prototype = empty_function;
1092 Handle<JSFunction> function_fun =
1093 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
1094 prototype, Builtins::kFunctionConstructor);
1095 function_fun->set_prototype_or_initial_map(
1096 *sloppy_function_map_writable_prototype_);
1097 function_fun->shared()->DontAdaptArguments();
1098 function_fun->shared()->set_construct_stub(
1099 *isolate->builtins()->FunctionConstructor());
1100 function_fun->shared()->set_length(1);
1101 InstallWithIntrinsicDefaultProto(isolate, function_fun,
1102 Context::FUNCTION_FUNCTION_INDEX);
1103
1104 // Setup the methods on the %FunctionPrototype%.
1105 SimpleInstallFunction(prototype, factory->apply_string(),
1106 Builtins::kFunctionPrototypeApply, 2, false);
1107 SimpleInstallFunction(prototype, factory->bind_string(),
1108 Builtins::kFunctionPrototypeBind, 1, false);
1109 SimpleInstallFunction(prototype, factory->call_string(),
1110 Builtins::kFunctionPrototypeCall, 1, false);
1111 SimpleInstallFunction(prototype, factory->toString_string(),
1112 Builtins::kFunctionPrototypeToString, 0, false);
1113
Ben Murdoch097c5b22016-05-18 11:27:45 +01001114 // Install the @@hasInstance function.
1115 Handle<JSFunction> has_instance = InstallFunction(
1116 prototype, factory->has_instance_symbol(), JS_OBJECT_TYPE,
1117 JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1118 Builtins::kFunctionHasInstance,
1119 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY));
1120
1121 // Set the expected parameters for @@hasInstance to 1; required by builtin.
1122 has_instance->shared()->set_internal_formal_parameter_count(1);
1123
1124 // Set the length for the function to satisfy ECMA-262.
1125 has_instance->shared()->set_length(1);
1126
1127 // Install in the native context
1128 native_context()->set_ordinary_has_instance(*has_instance);
1129
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001130 // Install the "constructor" property on the %FunctionPrototype%.
1131 JSObject::AddProperty(prototype, factory->constructor_string(),
1132 function_fun, DONT_ENUM);
1133
1134 sloppy_function_map_writable_prototype_->SetConstructor(*function_fun);
1135 strict_function_map_writable_prototype_->SetConstructor(*function_fun);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001136 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001137
1138 { // --- A r r a y ---
1139 Handle<JSFunction> array_function =
1140 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001141 isolate->initial_object_prototype(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001142 Builtins::kArrayCode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001143 array_function->shared()->DontAdaptArguments();
Ben Murdochda12d292016-06-02 14:46:10 +01001144 array_function->shared()->set_builtin_function_id(kArrayCode);
Steve Blocka7e24c12009-10-30 11:49:00 +00001145
1146 // This seems a bit hackish, but we need to make sure Array.length
1147 // is 1.
1148 array_function->shared()->set_length(1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001149
1150 Handle<Map> initial_map(array_function->initial_map());
1151
1152 // This assert protects an optimization in
1153 // HGraphBuilder::JSArrayBuilder::EmitMapCode()
1154 DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind());
1155 Map::EnsureDescriptorSlack(initial_map, 1);
1156
1157 PropertyAttributes attribs = static_cast<PropertyAttributes>(
1158 DONT_ENUM | DONT_DELETE);
1159
1160 Handle<AccessorInfo> array_length =
1161 Accessors::ArrayLengthInfo(isolate, attribs);
1162 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001163 AccessorConstantDescriptor d(
1164 Handle<Name>(Name::cast(array_length->name())), array_length,
1165 attribs);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001166 initial_map->AppendDescriptor(&d);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001167 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001168
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001169 InstallWithIntrinsicDefaultProto(isolate, array_function,
1170 Context::ARRAY_FUNCTION_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001171
1172 // Cache the array maps, needed by ArrayConstructorStub
1173 CacheInitialJSArrayMaps(native_context(), initial_map);
1174 ArrayConstructorStub array_constructor_stub(isolate);
1175 Handle<Code> code = array_constructor_stub.GetCode();
1176 array_function->shared()->set_construct_stub(*code);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001177
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001178 Handle<JSFunction> is_arraylike = SimpleInstallFunction(
1179 array_function, isolate->factory()->InternalizeUtf8String("isArray"),
1180 Builtins::kArrayIsArray, 1, true);
1181 native_context()->set_is_arraylike(*is_arraylike);
Steve Blocka7e24c12009-10-30 11:49:00 +00001182 }
1183
1184 { // --- N u m b e r ---
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001185 Handle<JSFunction> number_fun = InstallFunction(
1186 global, "Number", JS_VALUE_TYPE, JSValue::kSize,
1187 isolate->initial_object_prototype(), Builtins::kNumberConstructor);
1188 number_fun->shared()->DontAdaptArguments();
1189 number_fun->shared()->set_construct_stub(
1190 *isolate->builtins()->NumberConstructor_ConstructStub());
1191 number_fun->shared()->set_length(1);
1192 InstallWithIntrinsicDefaultProto(isolate, number_fun,
1193 Context::NUMBER_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00001194 }
1195
1196 { // --- B o o l e a n ---
1197 Handle<JSFunction> boolean_fun =
1198 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001199 isolate->initial_object_prototype(),
Ben Murdoch097c5b22016-05-18 11:27:45 +01001200 Builtins::kBooleanConstructor);
1201 boolean_fun->shared()->DontAdaptArguments();
1202 boolean_fun->shared()->set_construct_stub(
1203 *isolate->builtins()->BooleanConstructor_ConstructStub());
1204 boolean_fun->shared()->set_length(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001205 InstallWithIntrinsicDefaultProto(isolate, boolean_fun,
1206 Context::BOOLEAN_FUNCTION_INDEX);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001207
1208 // Create the %BooleanPrototype%
1209 Handle<JSValue> prototype =
1210 Handle<JSValue>::cast(factory->NewJSObject(boolean_fun, TENURED));
1211 prototype->set_value(isolate->heap()->false_value());
1212 Accessors::FunctionSetPrototype(boolean_fun, prototype).Assert();
1213
1214 // Install the "constructor" property on the {prototype}.
1215 JSObject::AddProperty(prototype, factory->constructor_string(), boolean_fun,
1216 DONT_ENUM);
1217
1218 // Install the Boolean.prototype methods.
1219 SimpleInstallFunction(prototype, "toString",
1220 Builtins::kBooleanPrototypeToString, 0, false);
1221 SimpleInstallFunction(prototype, "valueOf",
1222 Builtins::kBooleanPrototypeValueOf, 0, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001223 }
1224
1225 { // --- S t r i n g ---
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001226 Handle<JSFunction> string_fun = InstallFunction(
1227 global, "String", JS_VALUE_TYPE, JSValue::kSize,
1228 isolate->initial_object_prototype(), Builtins::kStringConstructor);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001229 string_fun->shared()->set_construct_stub(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001230 *isolate->builtins()->StringConstructor_ConstructStub());
1231 string_fun->shared()->DontAdaptArguments();
1232 string_fun->shared()->set_length(1);
1233 InstallWithIntrinsicDefaultProto(isolate, string_fun,
1234 Context::STRING_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00001235
1236 Handle<Map> string_map =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001237 Handle<Map>(native_context()->string_function()->initial_map());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001238 string_map->set_elements_kind(FAST_STRING_WRAPPER_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001239 Map::EnsureDescriptorSlack(string_map, 1);
1240
1241 PropertyAttributes attribs = static_cast<PropertyAttributes>(
1242 DONT_ENUM | DONT_DELETE | READ_ONLY);
1243 Handle<AccessorInfo> string_length(
1244 Accessors::StringLengthInfo(isolate, attribs));
1245
1246 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001247 AccessorConstantDescriptor d(factory->length_string(), string_length,
1248 attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001249 string_map->AppendDescriptor(&d);
1250 }
Ben Murdochda12d292016-06-02 14:46:10 +01001251
1252 // Install the String.fromCharCode function.
1253 SimpleInstallFunction(string_fun, "fromCharCode",
1254 Builtins::kStringFromCharCode, 1, false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001255 }
1256
1257 {
1258 // --- S y m b o l ---
Ben Murdoch097c5b22016-05-18 11:27:45 +01001259 Handle<JSObject> prototype =
1260 factory->NewJSObject(isolate->object_function(), TENURED);
1261 Handle<JSFunction> symbol_fun =
1262 InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
1263 prototype, Builtins::kSymbolConstructor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001264 symbol_fun->shared()->set_construct_stub(
1265 *isolate->builtins()->SymbolConstructor_ConstructStub());
Ben Murdochda12d292016-06-02 14:46:10 +01001266 symbol_fun->shared()->set_length(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001267 symbol_fun->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001268 native_context()->set_symbol_function(*symbol_fun);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001269
1270 // Install the "constructor" property on the {prototype}.
1271 JSObject::AddProperty(prototype, factory->constructor_string(), symbol_fun,
1272 DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001273 }
1274
1275 { // --- D a t e ---
1276 // Builtin functions for Date.prototype.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001277 Handle<JSObject> prototype =
1278 factory->NewJSObject(isolate->object_function(), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001279 Handle<JSFunction> date_fun =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001280 InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, prototype,
1281 Builtins::kDateConstructor);
1282 InstallWithIntrinsicDefaultProto(isolate, date_fun,
1283 Context::DATE_FUNCTION_INDEX);
1284 date_fun->shared()->set_construct_stub(
1285 *isolate->builtins()->DateConstructor_ConstructStub());
1286 date_fun->shared()->set_length(7);
1287 date_fun->shared()->DontAdaptArguments();
Steve Blocka7e24c12009-10-30 11:49:00 +00001288
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001289 // Install the Date.now, Date.parse and Date.UTC functions.
1290 SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
1291 SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
1292 SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);
1293
1294 // Install the "constructor" property on the {prototype}.
1295 JSObject::AddProperty(prototype, factory->constructor_string(), date_fun,
1296 DONT_ENUM);
1297
1298 // Install the Date.prototype methods.
1299 SimpleInstallFunction(prototype, "toString",
1300 Builtins::kDatePrototypeToString, 0, false);
1301 SimpleInstallFunction(prototype, "toDateString",
1302 Builtins::kDatePrototypeToDateString, 0, false);
1303 SimpleInstallFunction(prototype, "toTimeString",
1304 Builtins::kDatePrototypeToTimeString, 0, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001305 SimpleInstallFunction(prototype, "toISOString",
1306 Builtins::kDatePrototypeToISOString, 0, false);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001307 Handle<JSFunction> to_utc_string =
1308 SimpleInstallFunction(prototype, "toUTCString",
1309 Builtins::kDatePrototypeToUTCString, 0, false);
1310 InstallFunction(prototype, to_utc_string,
1311 factory->InternalizeUtf8String("toGMTString"), DONT_ENUM);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001312 SimpleInstallFunction(prototype, "getDate", Builtins::kDatePrototypeGetDate,
1313 0, true);
1314 SimpleInstallFunction(prototype, "setDate", Builtins::kDatePrototypeSetDate,
1315 1, false);
1316 SimpleInstallFunction(prototype, "getDay", Builtins::kDatePrototypeGetDay,
1317 0, true);
1318 SimpleInstallFunction(prototype, "getFullYear",
1319 Builtins::kDatePrototypeGetFullYear, 0, true);
1320 SimpleInstallFunction(prototype, "setFullYear",
1321 Builtins::kDatePrototypeSetFullYear, 3, false);
1322 SimpleInstallFunction(prototype, "getHours",
1323 Builtins::kDatePrototypeGetHours, 0, true);
1324 SimpleInstallFunction(prototype, "setHours",
1325 Builtins::kDatePrototypeSetHours, 4, false);
1326 SimpleInstallFunction(prototype, "getMilliseconds",
1327 Builtins::kDatePrototypeGetMilliseconds, 0, true);
1328 SimpleInstallFunction(prototype, "setMilliseconds",
1329 Builtins::kDatePrototypeSetMilliseconds, 1, false);
1330 SimpleInstallFunction(prototype, "getMinutes",
1331 Builtins::kDatePrototypeGetMinutes, 0, true);
1332 SimpleInstallFunction(prototype, "setMinutes",
1333 Builtins::kDatePrototypeSetMinutes, 3, false);
1334 SimpleInstallFunction(prototype, "getMonth",
1335 Builtins::kDatePrototypeGetMonth, 0, true);
1336 SimpleInstallFunction(prototype, "setMonth",
1337 Builtins::kDatePrototypeSetMonth, 2, false);
1338 SimpleInstallFunction(prototype, "getSeconds",
1339 Builtins::kDatePrototypeGetSeconds, 0, true);
1340 SimpleInstallFunction(prototype, "setSeconds",
1341 Builtins::kDatePrototypeSetSeconds, 2, false);
1342 SimpleInstallFunction(prototype, "getTime", Builtins::kDatePrototypeGetTime,
1343 0, true);
1344 SimpleInstallFunction(prototype, "setTime", Builtins::kDatePrototypeSetTime,
1345 1, false);
1346 SimpleInstallFunction(prototype, "getTimezoneOffset",
1347 Builtins::kDatePrototypeGetTimezoneOffset, 0, true);
1348 SimpleInstallFunction(prototype, "getUTCDate",
1349 Builtins::kDatePrototypeGetUTCDate, 0, true);
1350 SimpleInstallFunction(prototype, "setUTCDate",
1351 Builtins::kDatePrototypeSetUTCDate, 1, false);
1352 SimpleInstallFunction(prototype, "getUTCDay",
1353 Builtins::kDatePrototypeGetUTCDay, 0, true);
1354 SimpleInstallFunction(prototype, "getUTCFullYear",
1355 Builtins::kDatePrototypeGetUTCFullYear, 0, true);
1356 SimpleInstallFunction(prototype, "setUTCFullYear",
1357 Builtins::kDatePrototypeSetUTCFullYear, 3, false);
1358 SimpleInstallFunction(prototype, "getUTCHours",
1359 Builtins::kDatePrototypeGetUTCHours, 0, true);
1360 SimpleInstallFunction(prototype, "setUTCHours",
1361 Builtins::kDatePrototypeSetUTCHours, 4, false);
1362 SimpleInstallFunction(prototype, "getUTCMilliseconds",
1363 Builtins::kDatePrototypeGetUTCMilliseconds, 0, true);
1364 SimpleInstallFunction(prototype, "setUTCMilliseconds",
1365 Builtins::kDatePrototypeSetUTCMilliseconds, 1, false);
1366 SimpleInstallFunction(prototype, "getUTCMinutes",
1367 Builtins::kDatePrototypeGetUTCMinutes, 0, true);
1368 SimpleInstallFunction(prototype, "setUTCMinutes",
1369 Builtins::kDatePrototypeSetUTCMinutes, 3, false);
1370 SimpleInstallFunction(prototype, "getUTCMonth",
1371 Builtins::kDatePrototypeGetUTCMonth, 0, true);
1372 SimpleInstallFunction(prototype, "setUTCMonth",
1373 Builtins::kDatePrototypeSetUTCMonth, 2, false);
1374 SimpleInstallFunction(prototype, "getUTCSeconds",
1375 Builtins::kDatePrototypeGetUTCSeconds, 0, true);
1376 SimpleInstallFunction(prototype, "setUTCSeconds",
1377 Builtins::kDatePrototypeSetUTCSeconds, 2, false);
1378 SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
1379 0, false);
1380 SimpleInstallFunction(prototype, "getYear", Builtins::kDatePrototypeGetYear,
1381 0, true);
1382 SimpleInstallFunction(prototype, "setYear", Builtins::kDatePrototypeSetYear,
1383 1, false);
1384
1385 // Install i18n fallback functions.
1386 SimpleInstallFunction(prototype, "toLocaleString",
1387 Builtins::kDatePrototypeToString, 0, false);
1388 SimpleInstallFunction(prototype, "toLocaleDateString",
1389 Builtins::kDatePrototypeToDateString, 0, false);
1390 SimpleInstallFunction(prototype, "toLocaleTimeString",
1391 Builtins::kDatePrototypeToTimeString, 0, false);
1392
1393 // Install the @@toPrimitive function.
1394 Handle<JSFunction> to_primitive = InstallFunction(
1395 prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
1396 JSObject::kHeaderSize, MaybeHandle<JSObject>(),
1397 Builtins::kDatePrototypeToPrimitive,
1398 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
1399
1400 // Set the expected parameters for @@toPrimitive to 1; required by builtin.
1401 to_primitive->shared()->set_internal_formal_parameter_count(1);
1402
1403 // Set the length for the function to satisfy ECMA-262.
1404 to_primitive->shared()->set_length(1);
Steve Blocka7e24c12009-10-30 11:49:00 +00001405 }
1406
Steve Blocka7e24c12009-10-30 11:49:00 +00001407 { // -- R e g E x p
1408 // Builtin functions for RegExp.prototype.
1409 Handle<JSFunction> regexp_fun =
1410 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001411 isolate->initial_object_prototype(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001412 Builtins::kIllegal);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001413 InstallWithIntrinsicDefaultProto(isolate, regexp_fun,
1414 Context::REGEXP_FUNCTION_INDEX);
1415 regexp_fun->shared()->set_construct_stub(
1416 *isolate->builtins()->JSBuiltinsConstructStub());
Steve Block6ded16b2010-05-10 14:33:55 +01001417
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001418 DCHECK(regexp_fun->has_initial_map());
Steve Block6ded16b2010-05-10 14:33:55 +01001419 Handle<Map> initial_map(regexp_fun->initial_map());
1420
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001421 DCHECK_EQ(0, initial_map->GetInObjectProperties());
Steve Block6ded16b2010-05-10 14:33:55 +01001422
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001423 Map::EnsureDescriptorSlack(initial_map, 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001424
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001425 // ECMA-262, section 15.10.7.5.
1426 PropertyAttributes writable =
1427 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1428 DataDescriptor field(factory->last_index_string(),
1429 JSRegExp::kLastIndexFieldIndex, writable,
1430 Representation::Tagged());
1431 initial_map->AppendDescriptor(&field);
Steve Block6ded16b2010-05-10 14:33:55 +01001432
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001433 static const int num_fields = JSRegExp::kInObjectFieldCount;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001434 initial_map->SetInObjectProperties(num_fields);
Steve Block6ded16b2010-05-10 14:33:55 +01001435 initial_map->set_unused_property_fields(0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001436 initial_map->set_instance_size(initial_map->instance_size() +
1437 num_fields * kPointerSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00001438 }
1439
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001440 { // -- E r r o r
1441 Handle<JSFunction> error_fun = InstallFunction(
1442 global, "Error", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1443 isolate->initial_object_prototype(), Builtins::kIllegal);
1444 InstallWithIntrinsicDefaultProto(isolate, error_fun,
1445 Context::ERROR_FUNCTION_INDEX);
1446 }
1447
1448 { // -- E v a l E r r o r
1449 Handle<JSFunction> eval_error_fun = InstallFunction(
1450 global, "EvalError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1451 isolate->initial_object_prototype(), Builtins::kIllegal);
1452 InstallWithIntrinsicDefaultProto(isolate, eval_error_fun,
1453 Context::EVAL_ERROR_FUNCTION_INDEX);
1454 }
1455
1456 { // -- R a n g e E r r o r
1457 Handle<JSFunction> range_error_fun = InstallFunction(
1458 global, "RangeError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1459 isolate->initial_object_prototype(), Builtins::kIllegal);
1460 InstallWithIntrinsicDefaultProto(isolate, range_error_fun,
1461 Context::RANGE_ERROR_FUNCTION_INDEX);
1462 }
1463
1464 { // -- R e f e r e n c e E r r o r
1465 Handle<JSFunction> reference_error_fun = InstallFunction(
1466 global, "ReferenceError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1467 isolate->initial_object_prototype(), Builtins::kIllegal);
1468 InstallWithIntrinsicDefaultProto(isolate, reference_error_fun,
1469 Context::REFERENCE_ERROR_FUNCTION_INDEX);
1470 }
1471
1472 { // -- S y n t a x E r r o r
1473 Handle<JSFunction> syntax_error_fun = InstallFunction(
1474 global, "SyntaxError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1475 isolate->initial_object_prototype(), Builtins::kIllegal);
1476 InstallWithIntrinsicDefaultProto(isolate, syntax_error_fun,
1477 Context::SYNTAX_ERROR_FUNCTION_INDEX);
1478 }
1479
1480 { // -- T y p e E r r o r
1481 Handle<JSFunction> type_error_fun = InstallFunction(
1482 global, "TypeError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1483 isolate->initial_object_prototype(), Builtins::kIllegal);
1484 InstallWithIntrinsicDefaultProto(isolate, type_error_fun,
1485 Context::TYPE_ERROR_FUNCTION_INDEX);
1486 }
1487
1488 { // -- U R I E r r o r
1489 Handle<JSFunction> uri_error_fun = InstallFunction(
1490 global, "URIError", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1491 isolate->initial_object_prototype(), Builtins::kIllegal);
1492 InstallWithIntrinsicDefaultProto(isolate, uri_error_fun,
1493 Context::URI_ERROR_FUNCTION_INDEX);
1494 }
1495
1496 // Initialize the embedder data slot.
1497 Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
1498 native_context()->set_embedder_data(*embedder_data);
1499
1500 if (context_type == THIN_CONTEXT) return;
1501
Steve Blocka7e24c12009-10-30 11:49:00 +00001502 { // -- J S O N
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001503 Handle<String> name = factory->InternalizeUtf8String("JSON");
1504 Handle<JSFunction> cons = factory->NewFunction(name);
1505 JSFunction::SetInstancePrototype(cons,
1506 Handle<Object>(native_context()->initial_object_prototype(), isolate));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001507 cons->shared()->set_instance_class_name(*name);
Steve Block44f0eee2011-05-26 01:26:41 +01001508 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001509 DCHECK(json_object->IsJSObject());
1510 JSObject::AddProperty(global, name, json_object, DONT_ENUM);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001511 }
1512
1513 { // -- M a t h
1514 Handle<String> name = factory->InternalizeUtf8String("Math");
1515 Handle<JSFunction> cons = factory->NewFunction(name);
1516 JSFunction::SetInstancePrototype(
1517 cons,
1518 Handle<Object>(native_context()->initial_object_prototype(), isolate));
1519 cons->shared()->set_instance_class_name(*name);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001520 Handle<JSObject> math = factory->NewJSObject(cons, TENURED);
1521 DCHECK(math->IsJSObject());
1522 JSObject::AddProperty(global, name, math, DONT_ENUM);
Ben Murdochda12d292016-06-02 14:46:10 +01001523 SimpleInstallFunction(math, "acos", Builtins::kMathAcos, 1, true);
1524 SimpleInstallFunction(math, "asin", Builtins::kMathAsin, 1, true);
1525 SimpleInstallFunction(math, "atan", Builtins::kMathAtan, 1, true);
1526 SimpleInstallFunction(math, "ceil", Builtins::kMathCeil, 1, true);
1527 SimpleInstallFunction(math, "clz32", Builtins::kMathClz32, 1, true);
1528 Handle<JSFunction> math_floor =
1529 SimpleInstallFunction(math, "floor", Builtins::kMathFloor, 1, true);
1530 native_context()->set_math_floor(*math_floor);
1531 SimpleInstallFunction(math, "fround", Builtins::kMathFround, 1, true);
1532 SimpleInstallFunction(math, "imul", Builtins::kMathImul, 2, true);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001533 SimpleInstallFunction(math, "max", Builtins::kMathMax, 2, false);
1534 SimpleInstallFunction(math, "min", Builtins::kMathMin, 2, false);
Ben Murdochda12d292016-06-02 14:46:10 +01001535 SimpleInstallFunction(math, "round", Builtins::kMathRound, 1, true);
1536 Handle<JSFunction> math_sqrt =
1537 SimpleInstallFunction(math, "sqrt", Builtins::kMathSqrt, 1, true);
1538 native_context()->set_math_sqrt(*math_sqrt);
1539 SimpleInstallFunction(math, "trunc", Builtins::kMathTrunc, 1, true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001540 }
1541
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001542 { // -- A r r a y B u f f e r
1543 Handle<JSFunction> array_buffer_fun =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001544 InstallArrayBuffer(global, "ArrayBuffer");
1545 InstallWithIntrinsicDefaultProto(isolate, array_buffer_fun,
1546 Context::ARRAY_BUFFER_FUN_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001547 }
1548
1549 { // -- T y p e d A r r a y s
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001550#define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
1551 { \
1552 Handle<JSFunction> fun; \
1553 InstallTypedArray(#Type "Array", TYPE##_ELEMENTS, &fun); \
1554 InstallWithIntrinsicDefaultProto(isolate, fun, \
1555 Context::TYPE##_ARRAY_FUN_INDEX); \
1556 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001557 TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
1558#undef INSTALL_TYPED_ARRAY
1559
Ben Murdoch097c5b22016-05-18 11:27:45 +01001560 Handle<JSFunction> data_view_fun = InstallFunction(
1561 global, "DataView", JS_DATA_VIEW_TYPE,
1562 JSDataView::kSizeWithInternalFields,
1563 isolate->initial_object_prototype(), Builtins::kDataViewConstructor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001564 InstallWithIntrinsicDefaultProto(isolate, data_view_fun,
1565 Context::DATA_VIEW_FUN_INDEX);
1566 data_view_fun->shared()->set_construct_stub(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001567 *isolate->builtins()->DataViewConstructor_ConstructStub());
1568 data_view_fun->shared()->set_length(3);
1569 data_view_fun->shared()->DontAdaptArguments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001570 }
1571
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001572 { // -- M a p
1573 Handle<JSFunction> js_map_fun = InstallFunction(
1574 global, "Map", JS_MAP_TYPE, JSMap::kSize,
1575 isolate->initial_object_prototype(), Builtins::kIllegal);
1576 InstallWithIntrinsicDefaultProto(isolate, js_map_fun,
1577 Context::JS_MAP_FUN_INDEX);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001578 }
1579
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001580 { // -- S e t
1581 Handle<JSFunction> js_set_fun = InstallFunction(
1582 global, "Set", JS_SET_TYPE, JSSet::kSize,
1583 isolate->initial_object_prototype(), Builtins::kIllegal);
1584 InstallWithIntrinsicDefaultProto(isolate, js_set_fun,
1585 Context::JS_SET_FUN_INDEX);
1586 }
1587
1588 { // -- I t e r a t o r R e s u l t
1589 Handle<Map> map =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001590 factory->NewMap(JS_OBJECT_TYPE, JSIteratorResult::kSize);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001591 Map::SetPrototype(map, isolate->initial_object_prototype());
1592 Map::EnsureDescriptorSlack(map, 2);
1593
1594 { // value
1595 DataDescriptor d(factory->value_string(), JSIteratorResult::kValueIndex,
1596 NONE, Representation::Tagged());
1597 map->AppendDescriptor(&d);
1598 }
1599
1600 { // done
1601 DataDescriptor d(factory->done_string(), JSIteratorResult::kDoneIndex,
1602 NONE, Representation::Tagged());
1603 map->AppendDescriptor(&d);
1604 }
1605
Ben Murdoch097c5b22016-05-18 11:27:45 +01001606 map->SetConstructor(native_context()->object_function());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001607 map->SetInObjectProperties(2);
1608 native_context()->set_iterator_result_map(*map);
1609 }
1610
1611 { // -- W e a k M a p
1612 Handle<JSFunction> js_weak_map_fun = InstallFunction(
1613 global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1614 isolate->initial_object_prototype(), Builtins::kIllegal);
1615 InstallWithIntrinsicDefaultProto(isolate, js_weak_map_fun,
1616 Context::JS_WEAK_MAP_FUN_INDEX);
1617 }
1618
1619 { // -- W e a k S e t
1620 Handle<JSFunction> js_weak_set_fun = InstallFunction(
1621 global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
1622 isolate->initial_object_prototype(), Builtins::kIllegal);
1623 InstallWithIntrinsicDefaultProto(isolate, js_weak_set_fun,
1624 Context::JS_WEAK_SET_FUN_INDEX);
1625 }
1626
Ben Murdochda12d292016-06-02 14:46:10 +01001627 { // -- P r o x y
1628 CreateJSProxyMaps();
1629
1630 Handle<String> name = factory->Proxy_string();
1631 Handle<Code> code(isolate->builtins()->ProxyConstructor());
1632
1633 Handle<JSFunction> proxy_function =
1634 factory->NewFunction(isolate->proxy_function_map(),
1635 factory->Proxy_string(), MaybeHandle<Code>(code));
1636
1637 JSFunction::SetInitialMap(
1638 proxy_function, Handle<Map>(native_context()->proxy_map(), isolate),
1639 factory->null_value());
1640
1641 proxy_function->shared()->set_construct_stub(
1642 *isolate->builtins()->ProxyConstructor_ConstructStub());
1643 proxy_function->shared()->set_internal_formal_parameter_count(2);
1644 proxy_function->shared()->set_length(2);
1645
1646 native_context()->set_proxy_function(*proxy_function);
1647 InstallFunction(global, name, proxy_function, factory->Object_string());
1648 }
1649
1650 { // -- R e f l e c t
1651 Handle<String> reflect_string = factory->InternalizeUtf8String("Reflect");
1652 Handle<JSObject> reflect =
1653 factory->NewJSObject(isolate->object_function(), TENURED);
1654 JSObject::AddProperty(global, reflect_string, reflect, DONT_ENUM);
1655
1656 Handle<JSFunction> define_property =
1657 SimpleInstallFunction(reflect, factory->defineProperty_string(),
1658 Builtins::kReflectDefineProperty, 3, true);
1659 native_context()->set_reflect_define_property(*define_property);
1660
1661 Handle<JSFunction> delete_property =
1662 SimpleInstallFunction(reflect, factory->deleteProperty_string(),
1663 Builtins::kReflectDeleteProperty, 2, true);
1664 native_context()->set_reflect_delete_property(*delete_property);
1665
1666 Handle<JSFunction> apply = SimpleInstallFunction(
1667 reflect, factory->apply_string(), Builtins::kReflectApply, 3, false);
1668 native_context()->set_reflect_apply(*apply);
1669
1670 Handle<JSFunction> construct =
1671 SimpleInstallFunction(reflect, factory->construct_string(),
1672 Builtins::kReflectConstruct, 2, false);
1673 native_context()->set_reflect_construct(*construct);
1674
1675 SimpleInstallFunction(reflect, factory->get_string(), Builtins::kReflectGet,
1676 2, false);
1677 SimpleInstallFunction(reflect, factory->getOwnPropertyDescriptor_string(),
1678 Builtins::kReflectGetOwnPropertyDescriptor, 2, true);
1679 SimpleInstallFunction(reflect, factory->getPrototypeOf_string(),
1680 Builtins::kReflectGetPrototypeOf, 1, true);
1681 SimpleInstallFunction(reflect, factory->has_string(), Builtins::kReflectHas,
1682 2, true);
1683 SimpleInstallFunction(reflect, factory->isExtensible_string(),
1684 Builtins::kReflectIsExtensible, 1, true);
1685 SimpleInstallFunction(reflect, factory->ownKeys_string(),
1686 Builtins::kReflectOwnKeys, 1, true);
1687 SimpleInstallFunction(reflect, factory->preventExtensions_string(),
1688 Builtins::kReflectPreventExtensions, 1, true);
1689 SimpleInstallFunction(reflect, factory->set_string(), Builtins::kReflectSet,
1690 3, false);
1691 SimpleInstallFunction(reflect, factory->setPrototypeOf_string(),
1692 Builtins::kReflectSetPrototypeOf, 2, true);
1693 }
1694
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001695 { // --- B o u n d F u n c t i o n
1696 Handle<Map> map =
1697 factory->NewMap(JS_BOUND_FUNCTION_TYPE, JSBoundFunction::kSize);
1698 map->set_is_callable();
1699 Map::SetPrototype(map, empty_function);
1700
1701 PropertyAttributes roc_attribs =
1702 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
1703 Map::EnsureDescriptorSlack(map, 2);
1704
1705 { // length
1706 DataDescriptor d(factory->length_string(), JSBoundFunction::kLengthIndex,
1707 roc_attribs, Representation::Tagged());
1708 map->AppendDescriptor(&d);
1709 }
1710 { // name
1711 DataDescriptor d(factory->name_string(), JSBoundFunction::kNameIndex,
1712 roc_attribs, Representation::Tagged());
1713 map->AppendDescriptor(&d);
1714 }
1715
1716 map->SetInObjectProperties(2);
1717 native_context()->set_bound_function_without_constructor_map(*map);
1718
1719 map = Map::Copy(map, "IsConstructor");
Ben Murdoch097c5b22016-05-18 11:27:45 +01001720 map->set_is_constructor(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001721 native_context()->set_bound_function_with_constructor_map(*map);
1722 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001723
1724 { // --- sloppy arguments map
Steve Blocka7e24c12009-10-30 11:49:00 +00001725 // Make sure we can recognize argument objects at runtime.
1726 // This is done by introducing an anonymous function with
1727 // class_name equals 'Arguments'.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001728 Handle<String> arguments_string = factory->Arguments_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001729 Handle<Code> code = isolate->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001730 Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
1731 arguments_string, code);
1732 function->shared()->set_instance_class_name(*arguments_string);
Steve Blocka7e24c12009-10-30 11:49:00 +00001733
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001734 Handle<Map> map = factory->NewMap(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001735 JS_OBJECT_TYPE, JSSloppyArgumentsObject::kSize, FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001736 // Create the descriptor array for the arguments object.
1737 Map::EnsureDescriptorSlack(map, 2);
Steve Blocka7e24c12009-10-30 11:49:00 +00001738
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001739 { // length
Ben Murdoch097c5b22016-05-18 11:27:45 +01001740 DataDescriptor d(factory->length_string(),
1741 JSSloppyArgumentsObject::kLengthIndex, DONT_ENUM,
1742 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001743 map->AppendDescriptor(&d);
1744 }
1745 { // callee
Ben Murdoch097c5b22016-05-18 11:27:45 +01001746 DataDescriptor d(factory->callee_string(),
1747 JSSloppyArgumentsObject::kCalleeIndex, DONT_ENUM,
1748 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001749 map->AppendDescriptor(&d);
1750 }
1751 // @@iterator method is added later.
Steve Blocka7e24c12009-10-30 11:49:00 +00001752
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001753 map->SetInObjectProperties(2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001754 native_context()->set_sloppy_arguments_map(*map);
Steve Blocka7e24c12009-10-30 11:49:00 +00001755
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001756 DCHECK(!function->has_initial_map());
1757 JSFunction::SetInitialMap(function, map,
1758 isolate->initial_object_prototype());
Steve Blocka7e24c12009-10-30 11:49:00 +00001759
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001760 DCHECK(!map->is_dictionary_map());
1761 DCHECK(IsFastObjectElementsKind(map->elements_kind()));
Steve Block44f0eee2011-05-26 01:26:41 +01001762 }
1763
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001764 { // --- fast and slow aliased arguments map
1765 Handle<Map> map = isolate->sloppy_arguments_map();
1766 map = Map::Copy(map, "FastAliasedArguments");
1767 map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
1768 DCHECK_EQ(2, map->GetInObjectProperties());
1769 native_context()->set_fast_aliased_arguments_map(*map);
1770
1771 map = Map::Copy(map, "SlowAliasedArguments");
1772 map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
1773 DCHECK_EQ(2, map->GetInObjectProperties());
1774 native_context()->set_slow_aliased_arguments_map(*map);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001775 }
1776
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001777 { // --- strict mode arguments map
Steve Block44f0eee2011-05-26 01:26:41 +01001778 const PropertyAttributes attributes =
1779 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1780
1781 // Create the ThrowTypeError functions.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001782 Handle<AccessorPair> callee = factory->NewAccessorPair();
1783 Handle<AccessorPair> caller = factory->NewAccessorPair();
Steve Block44f0eee2011-05-26 01:26:41 +01001784
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001785 Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
Steve Block44f0eee2011-05-26 01:26:41 +01001786
1787 // Install the ThrowTypeError functions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001788 callee->set_getter(*poison);
1789 callee->set_setter(*poison);
1790 caller->set_getter(*poison);
1791 caller->set_setter(*poison);
Steve Block44f0eee2011-05-26 01:26:41 +01001792
1793 // Create the map. Allocate one in-object field for length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001794 Handle<Map> map = factory->NewMap(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001795 JS_OBJECT_TYPE, JSStrictArgumentsObject::kSize, FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001796 // Create the descriptor array for the arguments object.
1797 Map::EnsureDescriptorSlack(map, 3);
1798
1799 { // length
Ben Murdoch097c5b22016-05-18 11:27:45 +01001800 DataDescriptor d(factory->length_string(),
1801 JSStrictArgumentsObject::kLengthIndex, DONT_ENUM,
1802 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001803 map->AppendDescriptor(&d);
1804 }
1805 { // callee
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001806 AccessorConstantDescriptor d(factory->callee_string(), callee,
1807 attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001808 map->AppendDescriptor(&d);
1809 }
1810 { // caller
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001811 AccessorConstantDescriptor d(factory->caller_string(), caller,
1812 attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001813 map->AppendDescriptor(&d);
1814 }
1815 // @@iterator method is added later.
1816
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001817 DCHECK_EQ(native_context()->object_function()->prototype(),
1818 *isolate->initial_object_prototype());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001819 Map::SetPrototype(map, isolate->initial_object_prototype());
1820 map->SetInObjectProperties(1);
Steve Block44f0eee2011-05-26 01:26:41 +01001821
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001822 // Copy constructor from the sloppy arguments boilerplate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001823 map->SetConstructor(
1824 native_context()->sloppy_arguments_map()->GetConstructor());
Steve Block44f0eee2011-05-26 01:26:41 +01001825
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001826 native_context()->set_strict_arguments_map(*map);
Steve Block44f0eee2011-05-26 01:26:41 +01001827
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001828 DCHECK(!map->is_dictionary_map());
1829 DCHECK(IsFastObjectElementsKind(map->elements_kind()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001830 }
1831
1832 { // --- context extension
1833 // Create a function for the context extension objects.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001834 Handle<Code> code = isolate->builtins()->Illegal();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001835 Handle<JSFunction> context_extension_fun = factory->NewFunction(
1836 factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1837 JSObject::kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00001838
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001839 Handle<String> name = factory->InternalizeOneByteString(
1840 STATIC_CHAR_VECTOR("context_extension"));
Steve Blocka7e24c12009-10-30 11:49:00 +00001841 context_extension_fun->shared()->set_instance_class_name(*name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001842 native_context()->set_context_extension_function(*context_extension_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001843 }
1844
1845
1846 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001847 // Set up the call-as-function delegate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001848 Handle<Code> code = isolate->builtins()->HandleApiCallAsFunction();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001849 Handle<JSFunction> delegate = factory->NewFunction(
1850 factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1851 native_context()->set_call_as_function_delegate(*delegate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001852 delegate->shared()->DontAdaptArguments();
1853 }
1854
1855 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001856 // Set up the call-as-constructor delegate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001857 Handle<Code> code = isolate->builtins()->HandleApiCallAsConstructor();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001858 Handle<JSFunction> delegate = factory->NewFunction(
1859 factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1860 native_context()->set_call_as_constructor_delegate(*delegate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001861 delegate->shared()->DontAdaptArguments();
1862 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001863} // NOLINT(readability/fn_size)
Steve Blocka7e24c12009-10-30 11:49:00 +00001864
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001865
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001866void Genesis::InstallTypedArray(const char* name, ElementsKind elements_kind,
1867 Handle<JSFunction>* fun) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001868 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
1869 Handle<JSFunction> result = InstallFunction(
1870 global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize,
1871 isolate()->initial_object_prototype(), Builtins::kIllegal);
1872
1873 Handle<Map> initial_map = isolate()->factory()->NewMap(
1874 JS_TYPED_ARRAY_TYPE,
1875 JSTypedArray::kSizeWithInternalFields,
1876 elements_kind);
1877 JSFunction::SetInitialMap(result, initial_map,
1878 handle(initial_map->prototype(), isolate()));
1879 *fun = result;
Steve Blocka7e24c12009-10-30 11:49:00 +00001880}
1881
1882
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001883void Genesis::InitializeExperimentalGlobal() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001884#define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001885
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001886 HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
1887 HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
1888 HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001889 FEATURE_INITIALIZE_GLOBAL(promise_extra, "")
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001890#undef FEATURE_INITIALIZE_GLOBAL
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001891}
1892
1893
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001894bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001895 Vector<const char> name = Natives::GetScriptName(index);
Steve Block44f0eee2011-05-26 01:26:41 +01001896 Handle<String> source_code =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001897 isolate->bootstrapper()->SourceLookup<Natives>(index);
1898
1899 // We pass in extras_utils so that builtin code can set it up for later use
1900 // by actual extras code, compiled with CompileExtraBuiltin.
1901 Handle<Object> global = isolate->global_object();
1902 Handle<Object> utils = isolate->natives_utils_object();
1903 Handle<Object> extras_utils = isolate->extras_utils_object();
1904 Handle<Object> args[] = {global, utils, extras_utils};
1905
1906 return Bootstrapper::CompileNative(isolate, name, source_code,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001907 arraysize(args), args, NATIVES_CODE);
Ben Murdoch257744e2011-11-30 15:57:28 +00001908}
1909
1910
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001911bool Bootstrapper::CompileExperimentalBuiltin(Isolate* isolate, int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001912 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001913 Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1914 Handle<String> source_code =
1915 isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index);
1916 Handle<Object> global = isolate->global_object();
1917 Handle<Object> utils = isolate->natives_utils_object();
1918 Handle<Object> args[] = {global, utils};
1919 return Bootstrapper::CompileNative(isolate, name, source_code,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001920 arraysize(args), args, NATIVES_CODE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001921}
1922
1923
1924bool Bootstrapper::CompileExtraBuiltin(Isolate* isolate, int index) {
1925 HandleScope scope(isolate);
1926 Vector<const char> name = ExtraNatives::GetScriptName(index);
1927 Handle<String> source_code =
1928 isolate->bootstrapper()->SourceLookup<ExtraNatives>(index);
1929 Handle<Object> global = isolate->global_object();
1930 Handle<Object> binding = isolate->extras_binding_object();
1931 Handle<Object> extras_utils = isolate->extras_utils_object();
1932 Handle<Object> args[] = {global, binding, extras_utils};
1933 return Bootstrapper::CompileNative(isolate, name, source_code,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001934 arraysize(args), args, EXTENSION_CODE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001935}
1936
1937
1938bool Bootstrapper::CompileExperimentalExtraBuiltin(Isolate* isolate,
1939 int index) {
1940 HandleScope scope(isolate);
1941 Vector<const char> name = ExperimentalExtraNatives::GetScriptName(index);
1942 Handle<String> source_code =
1943 isolate->bootstrapper()->SourceLookup<ExperimentalExtraNatives>(index);
1944 Handle<Object> global = isolate->global_object();
1945 Handle<Object> binding = isolate->extras_binding_object();
1946 Handle<Object> extras_utils = isolate->extras_utils_object();
1947 Handle<Object> args[] = {global, binding, extras_utils};
1948 return Bootstrapper::CompileNative(isolate, name, source_code,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001949 arraysize(args), args, EXTENSION_CODE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001950}
1951
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001952bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
1953 Handle<String> source, int argc,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001954 Handle<Object> argv[],
1955 NativesFlag natives_flag) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001956 SuppressDebug compiling_natives(isolate->debug());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001957 // During genesis, the boilerplate for stack overflow won't work until the
1958 // environment has been at least partially initialized. Add a stack check
1959 // before entering JS code to catch overflow early.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001960 StackLimitCheck check(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001961 if (check.JsHasOverflowed(1 * KB)) {
1962 isolate->StackOverflow();
1963 return false;
1964 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001965
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001966 Handle<Context> context(isolate->context());
1967
1968 Handle<String> script_name =
1969 isolate->factory()->NewStringFromUtf8(name).ToHandleChecked();
Ben Murdochda12d292016-06-02 14:46:10 +01001970 Handle<SharedFunctionInfo> function_info =
1971 Compiler::GetSharedFunctionInfoForScript(
1972 source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
1973 context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag,
1974 false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001975 if (function_info.is_null()) return false;
1976
1977 DCHECK(context->IsNativeContext());
1978
1979 Handle<JSFunction> fun =
1980 isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info,
1981 context);
1982 Handle<Object> receiver = isolate->factory()->undefined_value();
1983
1984 // For non-extension scripts, run script to get the function wrapper.
1985 Handle<Object> wrapper;
1986 if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) {
1987 return false;
1988 }
1989 // Then run the function wrapper.
1990 return !Execution::Call(isolate, Handle<JSFunction>::cast(wrapper), receiver,
1991 argc, argv).is_null();
Steve Blocka7e24c12009-10-30 11:49:00 +00001992}
1993
1994
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001995bool Genesis::CallUtilsFunction(Isolate* isolate, const char* name) {
1996 Handle<JSObject> utils =
1997 Handle<JSObject>::cast(isolate->natives_utils_object());
1998 Handle<String> name_string =
1999 isolate->factory()->NewStringFromAsciiChecked(name);
2000 Handle<Object> fun = JSObject::GetDataProperty(utils, name_string);
2001 Handle<Object> receiver = isolate->factory()->undefined_value();
2002 Handle<Object> args[] = {utils};
2003 return !Execution::Call(isolate, fun, receiver, 1, args).is_null();
2004}
2005
2006
2007bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002008 Factory* factory = isolate->factory();
2009 HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01002010 Handle<SharedFunctionInfo> function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +00002011
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002012 Handle<String> source =
2013 isolate->factory()
2014 ->NewExternalStringFromOneByte(extension->source())
2015 .ToHandleChecked();
2016 DCHECK(source->IsOneByteRepresentation());
2017
Steve Blocka7e24c12009-10-30 11:49:00 +00002018 // If we can't find the function in the cache, we compile a new
2019 // function and insert it into the cache.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002020 Vector<const char> name = CStrVector(extension->name());
2021 SourceCodeCache* cache = isolate->bootstrapper()->extensions_cache();
2022 Handle<Context> context(isolate->context());
2023 DCHECK(context->IsNativeContext());
2024
2025 if (!cache->Lookup(name, &function_info)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002026 Handle<String> script_name =
2027 factory->NewStringFromUtf8(name).ToHandleChecked();
Ben Murdochda12d292016-06-02 14:46:10 +01002028 function_info = Compiler::GetSharedFunctionInfoForScript(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002029 source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
2030 context, extension, NULL, ScriptCompiler::kNoCompileOptions,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002031 EXTENSION_CODE, false);
Steve Block6ded16b2010-05-10 14:33:55 +01002032 if (function_info.is_null()) return false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002033 cache->Add(name, function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +00002034 }
2035
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002036 // Set up the function context. Conceptually, we should clone the
Steve Blocka7e24c12009-10-30 11:49:00 +00002037 // function before overwriting the context but since we're in a
2038 // single-threaded environment it is not strictly necessary.
Steve Blocka7e24c12009-10-30 11:49:00 +00002039 Handle<JSFunction> fun =
Steve Block44f0eee2011-05-26 01:26:41 +01002040 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
Steve Blocka7e24c12009-10-30 11:49:00 +00002041
Leon Clarke4515c472010-02-03 11:58:03 +00002042 // Call function using either the runtime object or the global
Steve Blocka7e24c12009-10-30 11:49:00 +00002043 // object as the receiver. Provide no parameters.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002044 Handle<Object> receiver = isolate->global_object();
2045 return !Execution::Call(isolate, fun, receiver, 0, NULL).is_null();
Steve Blocka7e24c12009-10-30 11:49:00 +00002046}
2047
2048
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002049static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
2050 const char* holder_expr) {
2051 Isolate* isolate = native_context->GetIsolate();
2052 Factory* factory = isolate->factory();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002053 Handle<JSGlobalObject> global(native_context->global_object());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002054 const char* period_pos = strchr(holder_expr, '.');
2055 if (period_pos == NULL) {
2056 return Handle<JSObject>::cast(
2057 Object::GetPropertyOrElement(
2058 global, factory->InternalizeUtf8String(holder_expr))
2059 .ToHandleChecked());
2060 }
2061 const char* inner = period_pos + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002062 DCHECK(!strchr(inner, '.'));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002063 Vector<const char> property(holder_expr,
2064 static_cast<int>(period_pos - holder_expr));
2065 Handle<String> property_string = factory->InternalizeUtf8String(property);
2066 DCHECK(!property_string.is_null());
2067 Handle<JSObject> object = Handle<JSObject>::cast(
Ben Murdochda12d292016-06-02 14:46:10 +01002068 JSReceiver::GetProperty(global, property_string).ToHandleChecked());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002069 if (strcmp("prototype", inner) == 0) {
2070 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
2071 return Handle<JSObject>(JSObject::cast(function->prototype()));
2072 }
2073 Handle<String> inner_string = factory->InternalizeUtf8String(inner);
2074 DCHECK(!inner_string.is_null());
2075 Handle<Object> value =
Ben Murdochda12d292016-06-02 14:46:10 +01002076 JSReceiver::GetProperty(object, inner_string).ToHandleChecked();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002077 return Handle<JSObject>::cast(value);
2078}
Steve Blocka7e24c12009-10-30 11:49:00 +00002079
Ben Murdoch097c5b22016-05-18 11:27:45 +01002080void Genesis::ConfigureUtilsObject(GlobalContextType context_type) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002081 switch (context_type) {
2082 // We still need the utils object to find debug functions.
2083 case DEBUG_CONTEXT:
2084 return;
2085 // Expose the natives in global if a valid name for it is specified.
2086 case FULL_CONTEXT: {
2087 // We still need the utils object after deserialization.
2088 if (isolate()->serializer_enabled()) return;
2089 if (FLAG_expose_natives_as == NULL) break;
2090 if (strlen(FLAG_expose_natives_as) == 0) break;
2091 HandleScope scope(isolate());
2092 Handle<String> natives_key =
2093 factory()->InternalizeUtf8String(FLAG_expose_natives_as);
2094 uint32_t dummy_index;
2095 if (natives_key->AsArrayIndex(&dummy_index)) break;
2096 Handle<Object> utils = isolate()->natives_utils_object();
2097 Handle<JSObject> global = isolate()->global_object();
2098 JSObject::AddProperty(global, natives_key, utils, DONT_ENUM);
2099 break;
2100 }
2101 case THIN_CONTEXT:
2102 break;
Ben Murdoch257744e2011-11-30 15:57:28 +00002103 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002104
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002105 // The utils object can be removed for cases that reach this point.
2106 native_context()->set_natives_utils_object(heap()->undefined_value());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002107}
2108
2109
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002110void Bootstrapper::ExportFromRuntime(Isolate* isolate,
2111 Handle<JSObject> container) {
2112 Factory* factory = isolate->factory();
2113 HandleScope scope(isolate);
2114 Handle<Context> native_context = isolate->native_context();
2115#define EXPORT_PRIVATE_SYMBOL(NAME) \
2116 Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
2117 JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
2118 PRIVATE_SYMBOL_LIST(EXPORT_PRIVATE_SYMBOL)
2119#undef EXPORT_PRIVATE_SYMBOL
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002120
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002121#define EXPORT_PUBLIC_SYMBOL(NAME, DESCRIPTION) \
2122 Handle<String> NAME##_name = factory->NewStringFromAsciiChecked(#NAME); \
2123 JSObject::AddProperty(container, NAME##_name, factory->NAME(), NONE);
2124 PUBLIC_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
2125 WELL_KNOWN_SYMBOL_LIST(EXPORT_PUBLIC_SYMBOL)
2126#undef EXPORT_PUBLIC_SYMBOL
2127
2128 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002129 Handle<JSFunction> to_string = InstallFunction(
2130 container, "object_to_string", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2131 MaybeHandle<JSObject>(), Builtins::kObjectProtoToString);
2132 to_string->shared()->DontAdaptArguments();
2133 to_string->shared()->set_length(0);
2134 native_context->set_object_to_string(*to_string);
2135 }
2136
2137 Handle<JSObject> iterator_prototype;
2138
2139 {
2140 PrototypeIterator iter(native_context->generator_object_prototype_map());
2141 iter.Advance(); // Advance to the prototype of generator_object_prototype.
2142 iterator_prototype = Handle<JSObject>(iter.GetCurrent<JSObject>());
2143
2144 JSObject::AddProperty(container,
2145 factory->InternalizeUtf8String("IteratorPrototype"),
2146 iterator_prototype, NONE);
2147 }
2148
2149 {
2150 PrototypeIterator iter(native_context->sloppy_generator_function_map());
2151 Handle<JSObject> generator_function_prototype(iter.GetCurrent<JSObject>());
2152
2153 JSObject::AddProperty(
2154 container, factory->InternalizeUtf8String("GeneratorFunctionPrototype"),
2155 generator_function_prototype, NONE);
2156
2157 static const bool kUseStrictFunctionMap = true;
2158 Handle<JSFunction> generator_function_function = InstallFunction(
2159 container, "GeneratorFunction", JS_FUNCTION_TYPE, JSFunction::kSize,
2160 generator_function_prototype, Builtins::kGeneratorFunctionConstructor,
2161 kUseStrictFunctionMap);
2162 generator_function_function->set_prototype_or_initial_map(
2163 native_context->sloppy_generator_function_map());
2164 generator_function_function->shared()->DontAdaptArguments();
2165 generator_function_function->shared()->set_construct_stub(
2166 *isolate->builtins()->GeneratorFunctionConstructor());
2167 generator_function_function->shared()->set_length(1);
2168 InstallWithIntrinsicDefaultProto(
2169 isolate, generator_function_function,
2170 Context::GENERATOR_FUNCTION_FUNCTION_INDEX);
2171
2172 native_context->sloppy_generator_function_map()->SetConstructor(
2173 *generator_function_function);
2174 native_context->strict_generator_function_map()->SetConstructor(
2175 *generator_function_function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002176 }
2177
2178 { // -- S e t I t e r a t o r
2179 Handle<JSObject> set_iterator_prototype =
2180 isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
2181 SetObjectPrototype(set_iterator_prototype, iterator_prototype);
2182 Handle<JSFunction> set_iterator_function = InstallFunction(
2183 container, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize,
2184 set_iterator_prototype, Builtins::kIllegal);
2185 native_context->set_set_iterator_map(set_iterator_function->initial_map());
2186 }
2187
2188 { // -- M a p I t e r a t o r
2189 Handle<JSObject> map_iterator_prototype =
2190 isolate->factory()->NewJSObject(isolate->object_function(), TENURED);
2191 SetObjectPrototype(map_iterator_prototype, iterator_prototype);
2192 Handle<JSFunction> map_iterator_function = InstallFunction(
2193 container, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize,
2194 map_iterator_prototype, Builtins::kIllegal);
2195 native_context->set_map_iterator_map(map_iterator_function->initial_map());
2196 }
2197
2198 { // -- S c r i p t
2199 // Builtin functions for Script.
2200 Handle<JSFunction> script_fun = InstallFunction(
2201 container, "Script", JS_VALUE_TYPE, JSValue::kSize,
2202 isolate->initial_object_prototype(), Builtins::kIllegal);
2203 Handle<JSObject> prototype =
2204 factory->NewJSObject(isolate->object_function(), TENURED);
2205 Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
2206 native_context->set_script_function(*script_fun);
2207
2208 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
2209 Map::EnsureDescriptorSlack(script_map, 15);
2210
2211 PropertyAttributes attribs =
2212 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2213
2214 Handle<AccessorInfo> script_column =
2215 Accessors::ScriptColumnOffsetInfo(isolate, attribs);
2216 {
2217 AccessorConstantDescriptor d(
2218 Handle<Name>(Name::cast(script_column->name())), script_column,
2219 attribs);
2220 script_map->AppendDescriptor(&d);
2221 }
2222
2223 Handle<AccessorInfo> script_id = Accessors::ScriptIdInfo(isolate, attribs);
2224 {
2225 AccessorConstantDescriptor d(Handle<Name>(Name::cast(script_id->name())),
2226 script_id, attribs);
2227 script_map->AppendDescriptor(&d);
2228 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002229
2230
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002231 Handle<AccessorInfo> script_name =
2232 Accessors::ScriptNameInfo(isolate, attribs);
2233 {
2234 AccessorConstantDescriptor d(
2235 Handle<Name>(Name::cast(script_name->name())), script_name, attribs);
2236 script_map->AppendDescriptor(&d);
2237 }
2238
2239 Handle<AccessorInfo> script_line =
2240 Accessors::ScriptLineOffsetInfo(isolate, attribs);
2241 {
2242 AccessorConstantDescriptor d(
2243 Handle<Name>(Name::cast(script_line->name())), script_line, attribs);
2244 script_map->AppendDescriptor(&d);
2245 }
2246
2247 Handle<AccessorInfo> script_source =
2248 Accessors::ScriptSourceInfo(isolate, attribs);
2249 {
2250 AccessorConstantDescriptor d(
2251 Handle<Name>(Name::cast(script_source->name())), script_source,
2252 attribs);
2253 script_map->AppendDescriptor(&d);
2254 }
2255
2256 Handle<AccessorInfo> script_type =
2257 Accessors::ScriptTypeInfo(isolate, attribs);
2258 {
2259 AccessorConstantDescriptor d(
2260 Handle<Name>(Name::cast(script_type->name())), script_type, attribs);
2261 script_map->AppendDescriptor(&d);
2262 }
2263
2264 Handle<AccessorInfo> script_compilation_type =
2265 Accessors::ScriptCompilationTypeInfo(isolate, attribs);
2266 {
2267 AccessorConstantDescriptor d(
2268 Handle<Name>(Name::cast(script_compilation_type->name())),
2269 script_compilation_type, attribs);
2270 script_map->AppendDescriptor(&d);
2271 }
2272
2273 Handle<AccessorInfo> script_line_ends =
2274 Accessors::ScriptLineEndsInfo(isolate, attribs);
2275 {
2276 AccessorConstantDescriptor d(
2277 Handle<Name>(Name::cast(script_line_ends->name())), script_line_ends,
2278 attribs);
2279 script_map->AppendDescriptor(&d);
2280 }
2281
2282 Handle<AccessorInfo> script_context_data =
2283 Accessors::ScriptContextDataInfo(isolate, attribs);
2284 {
2285 AccessorConstantDescriptor d(
2286 Handle<Name>(Name::cast(script_context_data->name())),
2287 script_context_data, attribs);
2288 script_map->AppendDescriptor(&d);
2289 }
2290
2291 Handle<AccessorInfo> script_eval_from_script =
2292 Accessors::ScriptEvalFromScriptInfo(isolate, attribs);
2293 {
2294 AccessorConstantDescriptor d(
2295 Handle<Name>(Name::cast(script_eval_from_script->name())),
2296 script_eval_from_script, attribs);
2297 script_map->AppendDescriptor(&d);
2298 }
2299
2300 Handle<AccessorInfo> script_eval_from_script_position =
2301 Accessors::ScriptEvalFromScriptPositionInfo(isolate, attribs);
2302 {
2303 AccessorConstantDescriptor d(
2304 Handle<Name>(Name::cast(script_eval_from_script_position->name())),
2305 script_eval_from_script_position, attribs);
2306 script_map->AppendDescriptor(&d);
2307 }
2308
2309 Handle<AccessorInfo> script_eval_from_function_name =
2310 Accessors::ScriptEvalFromFunctionNameInfo(isolate, attribs);
2311 {
2312 AccessorConstantDescriptor d(
2313 Handle<Name>(Name::cast(script_eval_from_function_name->name())),
2314 script_eval_from_function_name, attribs);
2315 script_map->AppendDescriptor(&d);
2316 }
2317
2318 Handle<AccessorInfo> script_source_url =
2319 Accessors::ScriptSourceUrlInfo(isolate, attribs);
2320 {
2321 AccessorConstantDescriptor d(
2322 Handle<Name>(Name::cast(script_source_url->name())),
2323 script_source_url, attribs);
2324 script_map->AppendDescriptor(&d);
2325 }
2326
2327 Handle<AccessorInfo> script_source_mapping_url =
2328 Accessors::ScriptSourceMappingUrlInfo(isolate, attribs);
2329 {
2330 AccessorConstantDescriptor d(
2331 Handle<Name>(Name::cast(script_source_mapping_url->name())),
2332 script_source_mapping_url, attribs);
2333 script_map->AppendDescriptor(&d);
2334 }
2335
2336 Handle<AccessorInfo> script_is_embedder_debug_script =
2337 Accessors::ScriptIsEmbedderDebugScriptInfo(isolate, attribs);
2338 {
2339 AccessorConstantDescriptor d(
2340 Handle<Name>(Name::cast(script_is_embedder_debug_script->name())),
2341 script_is_embedder_debug_script, attribs);
2342 script_map->AppendDescriptor(&d);
2343 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002344 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002345}
2346
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002347
2348void Bootstrapper::ExportExperimentalFromRuntime(Isolate* isolate,
2349 Handle<JSObject> container) {
2350 HandleScope scope(isolate);
2351
2352#define INITIALIZE_FLAG(FLAG) \
2353 { \
2354 Handle<String> name = \
2355 isolate->factory()->NewStringFromAsciiChecked(#FLAG); \
2356 JSObject::AddProperty(container, name, \
2357 isolate->factory()->ToBoolean(FLAG), NONE); \
2358 }
2359
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002360 INITIALIZE_FLAG(FLAG_harmony_species)
2361
2362#undef INITIALIZE_FLAG
2363}
2364
Steve Blocka7e24c12009-10-30 11:49:00 +00002365
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002366#define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
2367 void Genesis::InitializeGlobal_##id() {}
2368
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002369EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002370EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy_function)
2371EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy_let)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002372EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_observe)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002373EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode_regexps)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002374EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_do_expressions)
Ben Murdoch097c5b22016-05-18 11:27:45 +01002375EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_iterator_close)
Ben Murdochda12d292016-06-02 14:46:10 +01002376EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_exec)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002377EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_lookbehind)
Ben Murdoch097c5b22016-05-18 11:27:45 +01002378EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_property)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002379EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_name)
Ben Murdoch097c5b22016-05-18 11:27:45 +01002380EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_function_sent)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002381EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(promise_extra)
Ben Murdoch097c5b22016-05-18 11:27:45 +01002382EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tailcalls)
2383EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_instanceof)
Ben Murdochda12d292016-06-02 14:46:10 +01002384EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrictive_declarations)
2385EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_exponentiation_operator)
2386EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_string_padding)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002387
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002388void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
2389 const char* name, Handle<Symbol> value) {
2390 Handle<JSGlobalObject> global(
2391 JSGlobalObject::cast(native_context->global_object()));
2392 Handle<String> symbol_string = factory->InternalizeUtf8String("Symbol");
2393 Handle<JSObject> symbol = Handle<JSObject>::cast(
2394 JSObject::GetProperty(global, symbol_string).ToHandleChecked());
2395 Handle<String> name_string = factory->InternalizeUtf8String(name);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002396 PropertyAttributes attributes =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002397 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
2398 JSObject::AddProperty(symbol, name_string, value, attributes);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002399}
2400
Steve Blocka7e24c12009-10-30 11:49:00 +00002401
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002402void Genesis::InitializeGlobal_harmony_regexp_subclass() {
2403 if (!FLAG_harmony_regexp_subclass) return;
2404 InstallPublicSymbol(factory(), native_context(), "match",
2405 factory()->match_symbol());
2406 InstallPublicSymbol(factory(), native_context(), "replace",
2407 factory()->replace_symbol());
2408 InstallPublicSymbol(factory(), native_context(), "search",
2409 factory()->search_symbol());
2410 InstallPublicSymbol(factory(), native_context(), "split",
2411 factory()->split_symbol());
2412}
2413
2414
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002415void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
2416 if (!FLAG_harmony_sharedarraybuffer) return;
2417
2418 Handle<JSGlobalObject> global(native_context()->global_object());
2419 Handle<JSFunction> shared_array_buffer_fun =
2420 InstallArrayBuffer(global, "SharedArrayBuffer");
2421 native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun);
2422}
2423
2424
2425void Genesis::InitializeGlobal_harmony_simd() {
2426 if (!FLAG_harmony_simd) return;
2427
2428 Handle<JSGlobalObject> global(
2429 JSGlobalObject::cast(native_context()->global_object()));
2430 Isolate* isolate = global->GetIsolate();
2431 Factory* factory = isolate->factory();
2432
2433 Handle<String> name = factory->InternalizeUtf8String("SIMD");
2434 Handle<JSFunction> cons = factory->NewFunction(name);
2435 JSFunction::SetInstancePrototype(
2436 cons,
2437 Handle<Object>(native_context()->initial_object_prototype(), isolate));
2438 cons->shared()->set_instance_class_name(*name);
2439 Handle<JSObject> simd_object = factory->NewJSObject(cons, TENURED);
2440 DCHECK(simd_object->IsJSObject());
2441 JSObject::AddProperty(global, name, simd_object, DONT_ENUM);
2442
2443// Install SIMD type functions. Set the instance class names since
2444// InstallFunction only does this when we install on the JSGlobalObject.
2445#define SIMD128_INSTALL_FUNCTION(TYPE, Type, type, lane_count, lane_type) \
2446 Handle<JSFunction> type##_function = InstallFunction( \
2447 simd_object, #Type, JS_VALUE_TYPE, JSValue::kSize, \
2448 isolate->initial_object_prototype(), Builtins::kIllegal); \
2449 native_context()->set_##type##_function(*type##_function); \
2450 type##_function->shared()->set_instance_class_name(*factory->Type##_string());
2451 SIMD128_TYPES(SIMD128_INSTALL_FUNCTION)
2452#undef SIMD128_INSTALL_FUNCTION
2453}
2454
2455
Ben Murdoch097c5b22016-05-18 11:27:45 +01002456void Genesis::InitializeGlobal_harmony_object_values_entries() {
2457 if (!FLAG_harmony_object_values_entries) return;
2458
2459 Handle<JSGlobalObject> global(
2460 JSGlobalObject::cast(native_context()->global_object()));
2461 Isolate* isolate = global->GetIsolate();
2462 Factory* factory = isolate->factory();
2463
2464 Handle<JSFunction> object_function = isolate->object_function();
2465 SimpleInstallFunction(object_function, factory->entries_string(),
2466 Builtins::kObjectEntries, 1, false);
2467 SimpleInstallFunction(object_function, factory->values_string(),
2468 Builtins::kObjectValues, 1, false);
2469}
2470
2471void Genesis::InitializeGlobal_harmony_object_own_property_descriptors() {
2472 if (!FLAG_harmony_object_own_property_descriptors) return;
2473
2474 Handle<JSGlobalObject> global(
2475 JSGlobalObject::cast(native_context()->global_object()));
2476 Isolate* isolate = global->GetIsolate();
2477 Factory* factory = isolate->factory();
2478
2479 Handle<JSFunction> object_function = isolate->object_function();
2480 SimpleInstallFunction(object_function,
2481 factory->getOwnPropertyDescriptors_string(),
2482 Builtins::kObjectGetOwnPropertyDescriptors, 1, false);
2483}
2484
Ben Murdochda12d292016-06-02 14:46:10 +01002485void Genesis::InitializeGlobal_harmony_array_prototype_values() {
2486 if (!FLAG_harmony_array_prototype_values) return;
2487 Handle<JSFunction> array_constructor(native_context()->array_function());
2488 Handle<JSObject> array_prototype(
2489 JSObject::cast(array_constructor->instance_prototype()));
2490 Handle<Object> values_iterator =
2491 JSObject::GetProperty(array_prototype, factory()->iterator_symbol())
2492 .ToHandleChecked();
2493 DCHECK(values_iterator->IsJSFunction());
2494 JSObject::AddProperty(array_prototype, factory()->values_string(),
2495 values_iterator, DONT_ENUM);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002496
Ben Murdochda12d292016-06-02 14:46:10 +01002497 Handle<Object> unscopables =
2498 JSObject::GetProperty(array_prototype, factory()->unscopables_symbol())
2499 .ToHandleChecked();
2500 DCHECK(unscopables->IsJSObject());
2501 JSObject::AddProperty(Handle<JSObject>::cast(unscopables),
2502 factory()->values_string(), factory()->true_value(),
2503 NONE);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002504}
2505
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002506Handle<JSFunction> Genesis::InstallArrayBuffer(Handle<JSObject> target,
2507 const char* name) {
2508 // Setup the {prototype} with the given {name} for @@toStringTag.
2509 Handle<JSObject> prototype =
2510 factory()->NewJSObject(isolate()->object_function(), TENURED);
2511 JSObject::AddProperty(prototype, factory()->to_string_tag_symbol(),
2512 factory()->NewStringFromAsciiChecked(name),
2513 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
2514
2515 // Allocate the constructor with the given {prototype}.
2516 Handle<JSFunction> array_buffer_fun =
2517 InstallFunction(target, name, JS_ARRAY_BUFFER_TYPE,
2518 JSArrayBuffer::kSizeWithInternalFields, prototype,
2519 Builtins::kArrayBufferConstructor);
2520 array_buffer_fun->shared()->set_construct_stub(
2521 *isolate()->builtins()->ArrayBufferConstructor_ConstructStub());
2522 array_buffer_fun->shared()->DontAdaptArguments();
2523 array_buffer_fun->shared()->set_length(1);
2524
2525 // Install the "constructor" property on the {prototype}.
2526 JSObject::AddProperty(prototype, factory()->constructor_string(),
2527 array_buffer_fun, DONT_ENUM);
2528
2529 SimpleInstallFunction(array_buffer_fun, factory()->isView_string(),
2530 Builtins::kArrayBufferIsView, 1, true);
2531
2532 return array_buffer_fun;
2533}
2534
2535
2536void Genesis::InitializeGlobal_harmony_species() {
2537 if (!FLAG_harmony_species) return;
2538 InstallPublicSymbol(factory(), native_context(), "species",
2539 factory()->species_symbol());
2540}
2541
2542
2543Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
2544 const char* name,
2545 ElementsKind elements_kind) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002546 // --- I n t e r n a l A r r a y ---
2547 // An array constructor on the builtins object that works like
2548 // the public Array constructor, except that its prototype
2549 // doesn't inherit from Object.prototype.
2550 // To be used only for internal work by builtins. Instances
2551 // must not be leaked to user code.
2552 Handle<JSObject> prototype =
2553 factory()->NewJSObject(isolate()->object_function(), TENURED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002554 Handle<JSFunction> array_function =
2555 InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype,
2556 Builtins::kInternalArrayCode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002557
2558 InternalArrayConstructorStub internal_array_constructor_stub(isolate());
2559 Handle<Code> code = internal_array_constructor_stub.GetCode();
2560 array_function->shared()->set_construct_stub(*code);
2561 array_function->shared()->DontAdaptArguments();
2562
2563 Handle<Map> original_map(array_function->initial_map());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002564 Handle<Map> initial_map = Map::Copy(original_map, "InternalArray");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002565 initial_map->set_elements_kind(elements_kind);
2566 JSFunction::SetInitialMap(array_function, initial_map, prototype);
2567
2568 // Make "length" magic on instances.
2569 Map::EnsureDescriptorSlack(initial_map, 1);
2570
2571 PropertyAttributes attribs = static_cast<PropertyAttributes>(
2572 DONT_ENUM | DONT_DELETE);
2573
2574 Handle<AccessorInfo> array_length =
2575 Accessors::ArrayLengthInfo(isolate(), attribs);
2576 { // Add length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002577 AccessorConstantDescriptor d(Handle<Name>(Name::cast(array_length->name())),
2578 array_length, attribs);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002579 initial_map->AppendDescriptor(&d);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002580 }
2581
2582 return array_function;
2583}
2584
Ben Murdoch097c5b22016-05-18 11:27:45 +01002585bool Genesis::InstallNatives(GlobalContextType context_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002586 HandleScope scope(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00002587
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002588 // Set up the utils object as shared container between native scripts.
2589 Handle<JSObject> utils = factory()->NewJSObject(isolate()->object_function());
2590 JSObject::NormalizeProperties(utils, CLEAR_INOBJECT_PROPERTIES, 16,
2591 "utils container for native scripts");
2592 native_context()->set_natives_utils_object(*utils);
Steve Blocka7e24c12009-10-30 11:49:00 +00002593
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002594 // Set up the extras utils object as a shared container between native
2595 // scripts and extras. (Extras consume things added there by native scripts.)
2596 Handle<JSObject> extras_utils =
2597 factory()->NewJSObject(isolate()->object_function());
2598 native_context()->set_extras_utils_object(*extras_utils);
Steve Blocka7e24c12009-10-30 11:49:00 +00002599
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002600 InstallInternalArray(extras_utils, "InternalPackedArray", FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002601
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002602 int builtin_index = Natives::GetDebuggerCount();
2603 // Only run prologue.js and runtime.js at this point.
2604 DCHECK_EQ(builtin_index, Natives::GetIndex("prologue"));
2605 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
2606 DCHECK_EQ(builtin_index, Natives::GetIndex("runtime"));
2607 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002608
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002609 // A thin context is ready at this point.
2610 if (context_type == THIN_CONTEXT) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00002611
Steve Block6ded16b2010-05-10 14:33:55 +01002612 {
2613 // Builtin function for OpaqueReference -- a JSValue-based object,
2614 // that keeps its field isolated from JavaScript code. It may store
2615 // objects, that JavaScript code may not access.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002616 Handle<JSFunction> opaque_reference_fun = factory()->NewFunction(
2617 factory()->empty_string(), isolate()->builtins()->Illegal(),
2618 isolate()->initial_object_prototype(), JS_VALUE_TYPE, JSValue::kSize);
Steve Block6ded16b2010-05-10 14:33:55 +01002619 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00002620 factory()->NewJSObject(isolate()->object_function(), TENURED);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002621 Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002622 native_context()->set_opaque_reference_function(*opaque_reference_fun);
Steve Block6ded16b2010-05-10 14:33:55 +01002623 }
2624
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002625 // InternalArrays should not use Smi-Only array optimizations. There are too
2626 // many places in the C++ runtime code (e.g. RegEx) that assume that
2627 // elements in InternalArrays can be set to non-Smi values without going
2628 // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
2629 // transition easy to trap. Moreover, they rarely are smi-only.
2630 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002631 HandleScope scope(isolate());
2632 Handle<JSObject> utils =
2633 Handle<JSObject>::cast(isolate()->natives_utils_object());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002634 Handle<JSFunction> array_function =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002635 InstallInternalArray(utils, "InternalArray", FAST_HOLEY_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002636 native_context()->set_internal_array_function(*array_function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002637 InstallInternalArray(utils, "InternalPackedArray", FAST_ELEMENTS);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002638 }
2639
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002640 // Run the rest of the native scripts.
2641 while (builtin_index < Natives::GetBuiltinsCount()) {
2642 if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002643 }
2644
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002645 if (!CallUtilsFunction(isolate(), "PostNatives")) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002646
Ben Murdochda12d292016-06-02 14:46:10 +01002647 auto template_instantiations_cache = UnseededNumberDictionary::New(
2648 isolate(), ApiNatives::kInitialFunctionCacheSize);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002649 native_context()->set_template_instantiations_cache(
2650 *template_instantiations_cache);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002651
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002652 // Store the map for the %ObjectPrototype% after the natives has been compiled
2653 // and the Object function has been set up.
2654 Handle<JSFunction> object_function(native_context()->object_function());
2655 DCHECK(JSObject::cast(object_function->initial_map()->prototype())
2656 ->HasFastProperties());
2657 native_context()->set_object_function_prototype_map(
2658 HeapObject::cast(object_function->initial_map()->prototype())->map());
Ben Murdoche0cee9b2011-05-25 10:26:03 +01002659
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002660 // Store the map for the %StringPrototype% after the natives has been compiled
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002661 // and the String function has been set up.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002662 Handle<JSFunction> string_function(native_context()->string_function());
2663 DCHECK(JSObject::cast(
Iain Merrick75681382010-08-19 15:07:18 +01002664 string_function->initial_map()->prototype())->HasFastProperties());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002665 native_context()->set_string_function_prototype_map(
Iain Merrick75681382010-08-19 15:07:18 +01002666 HeapObject::cast(string_function->initial_map()->prototype())->map());
2667
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002668 // Install Global.eval.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002669 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002670 Handle<JSFunction> eval = SimpleInstallFunction(
2671 handle(native_context()->global_object()), factory()->eval_string(),
2672 Builtins::kGlobalEval, 1, false);
2673 native_context()->set_global_eval_fun(*eval);
2674 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002675
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002676 // Install Array.prototype.concat
2677 {
2678 Handle<JSFunction> array_constructor(native_context()->array_function());
2679 Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
2680 Handle<JSFunction> concat =
2681 InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2682 MaybeHandle<JSObject>(), Builtins::kArrayConcat);
Steve Blocka7e24c12009-10-30 11:49:00 +00002683
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002684 // Make sure that Array.prototype.concat appears to be compiled.
Steve Blocka7e24c12009-10-30 11:49:00 +00002685 // The code will never be called, but inline caching for call will
2686 // only work if it appears to be compiled.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002687 concat->shared()->DontAdaptArguments();
2688 DCHECK(concat->is_compiled());
Steve Blocka7e24c12009-10-30 11:49:00 +00002689 // Set the lengths for the functions to satisfy ECMA-262.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002690 concat->shared()->set_length(1);
2691 }
2692
2693 // Install InternalArray.prototype.concat
2694 {
2695 Handle<JSFunction> array_constructor(
2696 native_context()->internal_array_function());
2697 Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
2698 Handle<JSFunction> concat =
2699 InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2700 MaybeHandle<JSObject>(), Builtins::kArrayConcat);
2701
2702 // Make sure that InternalArray.prototype.concat appears to be compiled.
2703 // The code will never be called, but inline caching for call will
2704 // only work if it appears to be compiled.
2705 concat->shared()->DontAdaptArguments();
2706 DCHECK(concat->is_compiled());
2707 // Set the lengths for the functions to satisfy ECMA-262.
2708 concat->shared()->set_length(1);
2709 }
2710
2711 // Set up the Promise constructor.
2712 {
2713 Handle<String> key = factory()->Promise_string();
2714 Handle<JSFunction> function = Handle<JSFunction>::cast(
Ben Murdochda12d292016-06-02 14:46:10 +01002715 JSReceiver::GetProperty(handle(native_context()->global_object()), key)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002716 .ToHandleChecked());
2717 JSFunction::EnsureHasInitialMap(function);
2718 function->initial_map()->set_instance_type(JS_PROMISE_TYPE);
2719 function->shared()->set_construct_stub(
2720 *isolate()->builtins()->JSBuiltinsConstructStub());
2721 InstallWithIntrinsicDefaultProto(isolate(), function,
2722 Context::PROMISE_FUNCTION_INDEX);
Steve Blocka7e24c12009-10-30 11:49:00 +00002723 }
2724
Ben Murdoch42effa52011-08-19 16:40:31 +01002725 InstallBuiltinFunctionIds();
2726
Ben Murdochda12d292016-06-02 14:46:10 +01002727 // Also install builtin function ids to some generator object methods. These
2728 // three methods use the three resume operations (Runtime_GeneratorNext,
2729 // Runtime_GeneratorReturn, Runtime_GeneratorThrow) respectively. Those
2730 // operations are not supported by Crankshaft, TurboFan, nor Ignition.
2731 {
2732 Handle<JSObject> generator_object_prototype(JSObject::cast(
2733 native_context()->generator_object_prototype_map()->prototype()));
2734
2735 { // GeneratorObject.prototype.next
2736 Handle<String> key = factory()->next_string();
2737 Handle<JSFunction> function = Handle<JSFunction>::cast(
2738 JSReceiver::GetProperty(generator_object_prototype, key)
2739 .ToHandleChecked());
2740 function->shared()->set_builtin_function_id(kGeneratorObjectNext);
2741 }
2742 { // GeneratorObject.prototype.return
2743 Handle<String> key = factory()->NewStringFromAsciiChecked("return");
2744 Handle<JSFunction> function = Handle<JSFunction>::cast(
2745 JSReceiver::GetProperty(generator_object_prototype, key)
2746 .ToHandleChecked());
2747 function->shared()->set_builtin_function_id(kGeneratorObjectReturn);
2748 }
2749 { // GeneratorObject.prototype.throw
2750 Handle<String> key = factory()->throw_string();
2751 Handle<JSFunction> function = Handle<JSFunction>::cast(
2752 JSReceiver::GetProperty(generator_object_prototype, key)
2753 .ToHandleChecked());
2754 function->shared()->set_builtin_function_id(kGeneratorObjectThrow);
2755 }
2756 }
2757
Ben Murdoch097c5b22016-05-18 11:27:45 +01002758 // Create a map for accessor property descriptors (a variant of JSObject
2759 // that predefines four properties get, set, configurable and enumerable).
2760 {
2761 // AccessorPropertyDescriptor initial map.
2762 Handle<Map> map =
2763 factory()->NewMap(JS_OBJECT_TYPE, JSAccessorPropertyDescriptor::kSize);
2764 // Create the descriptor array for the property descriptor object.
2765 Map::EnsureDescriptorSlack(map, 4);
2766
2767 { // get
2768 DataDescriptor d(factory()->get_string(),
2769 JSAccessorPropertyDescriptor::kGetIndex, NONE,
2770 Representation::Tagged());
2771 map->AppendDescriptor(&d);
2772 }
2773 { // set
2774 DataDescriptor d(factory()->set_string(),
2775 JSAccessorPropertyDescriptor::kSetIndex, NONE,
2776 Representation::Tagged());
2777 map->AppendDescriptor(&d);
2778 }
2779 { // enumerable
2780 DataDescriptor d(factory()->enumerable_string(),
2781 JSAccessorPropertyDescriptor::kEnumerableIndex, NONE,
2782 Representation::Tagged());
2783 map->AppendDescriptor(&d);
2784 }
2785 { // configurable
2786 DataDescriptor d(factory()->configurable_string(),
2787 JSAccessorPropertyDescriptor::kConfigurableIndex, NONE,
2788 Representation::Tagged());
2789 map->AppendDescriptor(&d);
2790 }
2791
2792 Map::SetPrototype(map, isolate()->initial_object_prototype());
2793 map->SetConstructor(native_context()->object_function());
2794 map->SetInObjectProperties(4);
2795 map->set_unused_property_fields(0);
2796
2797 native_context()->set_accessor_property_descriptor_map(*map);
2798 }
2799
2800 // Create a map for data property descriptors (a variant of JSObject
2801 // that predefines four properties value, writable, configurable and
2802 // enumerable).
2803 {
2804 // DataPropertyDescriptor initial map.
2805 Handle<Map> map =
2806 factory()->NewMap(JS_OBJECT_TYPE, JSDataPropertyDescriptor::kSize);
2807 // Create the descriptor array for the property descriptor object.
2808 Map::EnsureDescriptorSlack(map, 4);
2809
2810 { // value
2811 DataDescriptor d(factory()->value_string(),
2812 JSDataPropertyDescriptor::kValueIndex, NONE,
2813 Representation::Tagged());
2814 map->AppendDescriptor(&d);
2815 }
2816 { // writable
2817 DataDescriptor d(factory()->writable_string(),
2818 JSDataPropertyDescriptor::kWritableIndex, NONE,
2819 Representation::Tagged());
2820 map->AppendDescriptor(&d);
2821 }
2822 { // enumerable
2823 DataDescriptor d(factory()->enumerable_string(),
2824 JSDataPropertyDescriptor::kEnumerableIndex, NONE,
2825 Representation::Tagged());
2826 map->AppendDescriptor(&d);
2827 }
2828 { // configurable
2829 DataDescriptor d(factory()->configurable_string(),
2830 JSDataPropertyDescriptor::kConfigurableIndex, NONE,
2831 Representation::Tagged());
2832 map->AppendDescriptor(&d);
2833 }
2834
2835 Map::SetPrototype(map, isolate()->initial_object_prototype());
2836 map->SetConstructor(native_context()->object_function());
2837 map->SetInObjectProperties(4);
2838 map->set_unused_property_fields(0);
2839
2840 native_context()->set_data_property_descriptor_map(*map);
2841 }
2842
Steve Block6ded16b2010-05-10 14:33:55 +01002843 // Create a constructor for RegExp results (a variant of Array that
2844 // predefines the two properties index and match).
2845 {
2846 // RegExpResult initial map.
2847
2848 // Find global.Array.prototype to inherit from.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002849 Handle<JSFunction> array_constructor(native_context()->array_function());
Steve Block6ded16b2010-05-10 14:33:55 +01002850 Handle<JSObject> array_prototype(
2851 JSObject::cast(array_constructor->instance_prototype()));
2852
2853 // Add initial map.
2854 Handle<Map> initial_map =
Ben Murdoch257744e2011-11-30 15:57:28 +00002855 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002856 initial_map->SetConstructor(*array_constructor);
Steve Block6ded16b2010-05-10 14:33:55 +01002857
2858 // Set prototype on map.
2859 initial_map->set_non_instance_prototype(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002860 Map::SetPrototype(initial_map, array_prototype);
Steve Block6ded16b2010-05-10 14:33:55 +01002861
2862 // Update map with length accessor from Array and add "index" and "input".
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002863 Map::EnsureDescriptorSlack(initial_map, 3);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002864
Steve Block6ded16b2010-05-10 14:33:55 +01002865 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002866 JSFunction* array_function = native_context()->array_function();
2867 Handle<DescriptorArray> array_descriptors(
2868 array_function->initial_map()->instance_descriptors());
2869 Handle<String> length = factory()->length_string();
2870 int old = array_descriptors->SearchWithCache(
Ben Murdoch097c5b22016-05-18 11:27:45 +01002871 isolate(), *length, array_function->initial_map());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002872 DCHECK(old != DescriptorArray::kNotFound);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002873 AccessorConstantDescriptor desc(
2874 length, handle(array_descriptors->GetValue(old), isolate()),
2875 array_descriptors->GetDetails(old).attributes());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002876 initial_map->AppendDescriptor(&desc);
2877 }
2878 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002879 DataDescriptor index_field(factory()->index_string(),
2880 JSRegExpResult::kIndexIndex, NONE,
2881 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002882 initial_map->AppendDescriptor(&index_field);
Steve Block6ded16b2010-05-10 14:33:55 +01002883 }
2884
2885 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002886 DataDescriptor input_field(factory()->input_string(),
2887 JSRegExpResult::kInputIndex, NONE,
2888 Representation::Tagged());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002889 initial_map->AppendDescriptor(&input_field);
Steve Block6ded16b2010-05-10 14:33:55 +01002890 }
Steve Block6ded16b2010-05-10 14:33:55 +01002891
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002892 initial_map->SetInObjectProperties(2);
Steve Block6ded16b2010-05-10 14:33:55 +01002893 initial_map->set_unused_property_fields(0);
Steve Block6ded16b2010-05-10 14:33:55 +01002894
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002895 native_context()->set_regexp_result_map(*initial_map);
Steve Block6ded16b2010-05-10 14:33:55 +01002896 }
2897
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002898 // Add @@iterator method to the arguments object maps.
2899 {
2900 PropertyAttributes attribs = DONT_ENUM;
2901 Handle<AccessorInfo> arguments_iterator =
2902 Accessors::ArgumentsIteratorInfo(isolate(), attribs);
2903 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002904 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2905 arguments_iterator, attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002906 Handle<Map> map(native_context()->sloppy_arguments_map());
2907 Map::EnsureDescriptorSlack(map, 1);
2908 map->AppendDescriptor(&d);
2909 }
2910 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002911 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2912 arguments_iterator, attribs);
2913 Handle<Map> map(native_context()->fast_aliased_arguments_map());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002914 Map::EnsureDescriptorSlack(map, 1);
2915 map->AppendDescriptor(&d);
2916 }
2917 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002918 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2919 arguments_iterator, attribs);
2920 Handle<Map> map(native_context()->slow_aliased_arguments_map());
2921 Map::EnsureDescriptorSlack(map, 1);
2922 map->AppendDescriptor(&d);
2923 }
2924 {
2925 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2926 arguments_iterator, attribs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002927 Handle<Map> map(native_context()->strict_arguments_map());
2928 Map::EnsureDescriptorSlack(map, 1);
2929 map->AppendDescriptor(&d);
2930 }
2931 }
2932
Steve Blocka7e24c12009-10-30 11:49:00 +00002933 return true;
2934}
2935
2936
Ben Murdoch257744e2011-11-30 15:57:28 +00002937bool Genesis::InstallExperimentalNatives() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002938 static const char* harmony_iterator_close_natives[] = {nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002939 static const char* harmony_sloppy_natives[] = {nullptr};
2940 static const char* harmony_sloppy_function_natives[] = {nullptr};
2941 static const char* harmony_sloppy_let_natives[] = {nullptr};
2942 static const char* harmony_species_natives[] = {"native harmony-species.js",
2943 nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01002944 static const char* harmony_tailcalls_natives[] = {nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002945 static const char* harmony_unicode_regexps_natives[] = {
2946 "native harmony-unicode-regexps.js", nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002947 static const char* harmony_object_observe_natives[] = {
2948 "native harmony-object-observe.js", nullptr};
2949 static const char* harmony_sharedarraybuffer_natives[] = {
2950 "native harmony-sharedarraybuffer.js", "native harmony-atomics.js", NULL};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002951 static const char* harmony_simd_natives[] = {"native harmony-simd.js",
2952 nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002953 static const char* harmony_do_expressions_natives[] = {nullptr};
Ben Murdochda12d292016-06-02 14:46:10 +01002954 static const char* harmony_regexp_exec_natives[] = {
2955 "native harmony-regexp-exec.js", nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002956 static const char* harmony_regexp_subclass_natives[] = {nullptr};
2957 static const char* harmony_regexp_lookbehind_natives[] = {nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01002958 static const char* harmony_instanceof_natives[] = {nullptr};
Ben Murdochda12d292016-06-02 14:46:10 +01002959 static const char* harmony_restrictive_declarations_natives[] = {nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01002960 static const char* harmony_regexp_property_natives[] = {nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002961 static const char* harmony_function_name_natives[] = {nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01002962 static const char* harmony_function_sent_natives[] = {nullptr};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002963 static const char* promise_extra_natives[] = {"native promise-extra.js",
2964 nullptr};
Ben Murdoch097c5b22016-05-18 11:27:45 +01002965 static const char* harmony_object_values_entries_natives[] = {nullptr};
2966 static const char* harmony_object_own_property_descriptors_natives[] = {
2967 nullptr};
Ben Murdochda12d292016-06-02 14:46:10 +01002968 static const char* harmony_array_prototype_values_natives[] = {nullptr};
2969 static const char* harmony_exponentiation_operator_natives[] = {nullptr};
2970 static const char* harmony_string_padding_natives[] = {
2971 "native harmony-string-padding.js", nullptr};
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002972
Ben Murdoch257744e2011-11-30 15:57:28 +00002973 for (int i = ExperimentalNatives::GetDebuggerCount();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002974 i < ExperimentalNatives::GetBuiltinsCount(); i++) {
2975#define INSTALL_EXPERIMENTAL_NATIVES(id, desc) \
2976 if (FLAG_##id) { \
2977 for (size_t j = 0; id##_natives[j] != NULL; j++) { \
2978 Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
2979 if (strncmp(script_name.start(), id##_natives[j], \
2980 script_name.length()) == 0) { \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002981 if (!Bootstrapper::CompileExperimentalBuiltin(isolate(), i)) { \
2982 return false; \
2983 } \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002984 } \
2985 } \
2986 }
2987 HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
2988 HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
2989 HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002990 INSTALL_EXPERIMENTAL_NATIVES(promise_extra, "");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002991#undef INSTALL_EXPERIMENTAL_NATIVES
Ben Murdoch257744e2011-11-30 15:57:28 +00002992 }
2993
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002994 if (!CallUtilsFunction(isolate(), "PostExperimentals")) return false;
2995
2996 InstallExperimentalBuiltinFunctionIds();
Ben Murdoch257744e2011-11-30 15:57:28 +00002997 return true;
2998}
2999
3000
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003001bool Genesis::InstallExtraNatives() {
3002 HandleScope scope(isolate());
3003
3004 Handle<JSObject> extras_binding =
3005 factory()->NewJSObject(isolate()->object_function());
3006 native_context()->set_extras_binding_object(*extras_binding);
3007
3008 for (int i = ExtraNatives::GetDebuggerCount();
3009 i < ExtraNatives::GetBuiltinsCount(); i++) {
3010 if (!Bootstrapper::CompileExtraBuiltin(isolate(), i)) return false;
3011 }
3012
3013 return true;
3014}
3015
3016
3017bool Genesis::InstallExperimentalExtraNatives() {
3018 for (int i = ExperimentalExtraNatives::GetDebuggerCount();
3019 i < ExperimentalExtraNatives::GetBuiltinsCount(); i++) {
3020 if (!Bootstrapper::CompileExperimentalExtraBuiltin(isolate(), i))
3021 return false;
3022 }
3023
3024 return true;
3025}
3026
3027
3028bool Genesis::InstallDebuggerNatives() {
3029 for (int i = 0; i < Natives::GetDebuggerCount(); ++i) {
3030 if (!Bootstrapper::CompileBuiltin(isolate(), i)) return false;
3031 }
3032 return CallUtilsFunction(isolate(), "PostDebug");
3033}
3034
3035
Ben Murdochb0fe1622011-05-05 13:52:32 +01003036static void InstallBuiltinFunctionId(Handle<JSObject> holder,
3037 const char* function_name,
3038 BuiltinFunctionId id) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003039 Isolate* isolate = holder->GetIsolate();
3040 Handle<Object> function_object =
Ben Murdochda12d292016-06-02 14:46:10 +01003041 JSReceiver::GetProperty(isolate, holder, function_name).ToHandleChecked();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003042 Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
Ben Murdochda12d292016-06-02 14:46:10 +01003043 function->shared()->set_builtin_function_id(id);
Kristian Monsen25f61362010-05-21 11:50:48 +01003044}
3045
3046
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003047#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
3048 { #holder_expr, #fun_name, k##name } \
3049 ,
3050
3051
Ben Murdochb0fe1622011-05-05 13:52:32 +01003052void Genesis::InstallBuiltinFunctionIds() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003053 HandleScope scope(isolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003054 struct BuiltinFunctionIds {
3055 const char* holder_expr;
3056 const char* fun_name;
3057 BuiltinFunctionId id;
3058 };
3059
3060 const BuiltinFunctionIds builtins[] = {
3061 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
3062
3063 for (const BuiltinFunctionIds& builtin : builtins) {
3064 Handle<JSObject> holder =
3065 ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
3066 InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
Kristian Monsen25f61362010-05-21 11:50:48 +01003067 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003068}
3069
3070
3071void Genesis::InstallExperimentalBuiltinFunctionIds() {
3072 if (FLAG_harmony_sharedarraybuffer) {
3073 struct BuiltinFunctionIds {
3074 const char* holder_expr;
3075 const char* fun_name;
3076 BuiltinFunctionId id;
3077 };
3078
3079 const BuiltinFunctionIds atomic_builtins[] = {
3080 ATOMIC_FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)};
3081
3082 for (const BuiltinFunctionIds& builtin : atomic_builtins) {
3083 Handle<JSObject> holder =
3084 ResolveBuiltinIdHolder(native_context(), builtin.holder_expr);
3085 InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id);
3086 }
3087 }
3088}
3089
3090
Ben Murdochb0fe1622011-05-05 13:52:32 +01003091#undef INSTALL_BUILTIN_ID
Steve Block6ded16b2010-05-10 14:33:55 +01003092
3093
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003094void Genesis::InitializeNormalizedMapCaches() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003095 Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
3096 native_context()->set_normalized_map_cache(*cache);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003097}
3098
3099
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003100bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +00003101 v8::ExtensionConfiguration* extensions) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003102 BootstrapperActive active(this);
3103 SaveContext saved_context(isolate_);
3104 isolate_->set_context(*native_context);
3105 return Genesis::InstallExtensions(native_context, extensions) &&
3106 Genesis::InstallSpecialObjects(native_context);
3107}
3108
3109
3110bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
3111 Isolate* isolate = native_context->GetIsolate();
3112 // Don't install extensions into the snapshot.
3113 if (isolate->serializer_enabled()) return true;
3114
3115 Factory* factory = isolate->factory();
3116 HandleScope scope(isolate);
3117 Handle<JSGlobalObject> global(JSGlobalObject::cast(
3118 native_context->global_object()));
3119
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003120 Handle<JSObject> Error = isolate->error_function();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003121 Handle<String> name =
3122 factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("stackTraceLimit"));
3123 Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate);
3124 JSObject::AddProperty(Error, name, stack_trace_limit, NONE);
3125
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003126 // Expose the debug global object in global if a name for it is specified.
3127 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
3128 // If loading fails we just bail out without installing the
3129 // debugger but without tanking the whole context.
3130 Debug* debug = isolate->debug();
3131 if (!debug->Load()) return true;
3132 Handle<Context> debug_context = debug->debug_context();
3133 // Set the security token for the debugger context to the same as
3134 // the shell native context to allow calling between these (otherwise
3135 // exposing debug global object doesn't make much sense).
3136 debug_context->set_security_token(native_context->security_token());
3137 Handle<String> debug_string =
3138 factory->InternalizeUtf8String(FLAG_expose_debug_as);
3139 uint32_t index;
3140 if (debug_string->AsArrayIndex(&index)) return true;
3141 Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
3142 JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM);
3143 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003144
3145 if (FLAG_expose_wasm) {
3146 WasmJs::Install(isolate, global);
3147 }
3148
Andrei Popescu31002712010-02-23 13:46:05 +00003149 return true;
3150}
3151
3152
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003153static uint32_t Hash(RegisteredExtension* extension) {
3154 return v8::internal::ComputePointerHash(extension);
3155}
3156
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003157
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003158Genesis::ExtensionStates::ExtensionStates() : map_(HashMap::PointersMatch, 8) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003159
3160Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
3161 RegisteredExtension* extension) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003162 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003163 if (entry == NULL) {
3164 return UNVISITED;
3165 }
3166 return static_cast<ExtensionTraversalState>(
3167 reinterpret_cast<intptr_t>(entry->value));
3168}
3169
3170void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
3171 ExtensionTraversalState state) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003172 map_.LookupOrInsert(extension, Hash(extension))->value =
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003173 reinterpret_cast<void*>(static_cast<intptr_t>(state));
3174}
Steve Blocka7e24c12009-10-30 11:49:00 +00003175
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003176
3177bool Genesis::InstallExtensions(Handle<Context> native_context,
Andrei Popescu31002712010-02-23 13:46:05 +00003178 v8::ExtensionConfiguration* extensions) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003179 Isolate* isolate = native_context->GetIsolate();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003180 ExtensionStates extension_states; // All extensions have state UNVISITED.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003181 return InstallAutoExtensions(isolate, &extension_states) &&
3182 (!FLAG_expose_free_buffer ||
3183 InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
3184 (!FLAG_expose_gc ||
3185 InstallExtension(isolate, "v8/gc", &extension_states)) &&
3186 (!FLAG_expose_externalize_string ||
3187 InstallExtension(isolate, "v8/externalize", &extension_states)) &&
3188 (!FLAG_track_gc_object_stats ||
3189 InstallExtension(isolate, "v8/statistics", &extension_states)) &&
3190 (!FLAG_expose_trigger_failure ||
3191 InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
3192 InstallRequestedExtensions(isolate, extensions, &extension_states);
3193}
Steve Blocka7e24c12009-10-30 11:49:00 +00003194
Steve Blocka7e24c12009-10-30 11:49:00 +00003195
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003196bool Genesis::InstallAutoExtensions(Isolate* isolate,
3197 ExtensionStates* extension_states) {
3198 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
3199 it != NULL;
3200 it = it->next()) {
3201 if (it->extension()->auto_enable() &&
3202 !InstallExtension(isolate, it, extension_states)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003203 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003204 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003205 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003206 return true;
3207}
Steve Blocka7e24c12009-10-30 11:49:00 +00003208
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003209
3210bool Genesis::InstallRequestedExtensions(Isolate* isolate,
3211 v8::ExtensionConfiguration* extensions,
3212 ExtensionStates* extension_states) {
3213 for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
3214 if (!InstallExtension(isolate, *it, extension_states)) return false;
3215 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003216 return true;
3217}
3218
3219
3220// Installs a named extension. This methods is unoptimized and does
3221// not scale well if we want to support a large number of extensions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003222bool Genesis::InstallExtension(Isolate* isolate,
3223 const char* name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003224 ExtensionStates* extension_states) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003225 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
3226 it != NULL;
3227 it = it->next()) {
3228 if (strcmp(name, it->extension()->name()) == 0) {
3229 return InstallExtension(isolate, it, extension_states);
3230 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003231 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003232 return Utils::ApiCheck(false,
3233 "v8::Context::New()",
3234 "Cannot find required extension");
Steve Blocka7e24c12009-10-30 11:49:00 +00003235}
3236
3237
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003238bool Genesis::InstallExtension(Isolate* isolate,
3239 v8::RegisteredExtension* current,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003240 ExtensionStates* extension_states) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003241 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003242
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003243 if (extension_states->get_state(current) == INSTALLED) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003244 // The current node has already been visited so there must be a
3245 // cycle in the dependency graph; fail.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003246 if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
3247 "v8::Context::New()",
3248 "Circular extension dependency")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003249 return false;
3250 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003251 DCHECK(extension_states->get_state(current) == UNVISITED);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003252 extension_states->set_state(current, VISITED);
Steve Blocka7e24c12009-10-30 11:49:00 +00003253 v8::Extension* extension = current->extension();
3254 // Install the extension's dependencies
3255 for (int i = 0; i < extension->dependency_count(); i++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003256 if (!InstallExtension(isolate,
3257 extension->dependencies()[i],
3258 extension_states)) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003259 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003260 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003261 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003262 // We do not expect this to throw an exception. Change this if it does.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003263 bool result = CompileExtension(isolate, extension);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003264 DCHECK(isolate->has_pending_exception() != result);
Steve Blocka7e24c12009-10-30 11:49:00 +00003265 if (!result) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003266 // We print out the name of the extension that fail to install.
3267 // When an error is thrown during bootstrapping we automatically print
3268 // the line number at which this happened to the console in the isolate
3269 // error throwing functionality.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003270 base::OS::PrintError("Error installing extension '%s'.\n",
3271 current->extension()->name());
Steve Block44f0eee2011-05-26 01:26:41 +01003272 isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00003273 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003274 extension_states->set_state(current, INSTALLED);
3275 isolate->NotifyExtensionInstalled();
Steve Blocka7e24c12009-10-30 11:49:00 +00003276 return result;
3277}
3278
3279
3280bool Genesis::ConfigureGlobalObjects(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003281 v8::Local<v8::ObjectTemplate> global_proxy_template) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003282 Handle<JSObject> global_proxy(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003283 JSObject::cast(native_context()->global_proxy()));
3284 Handle<JSObject> global_object(
3285 JSObject::cast(native_context()->global_object()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003286
3287 if (!global_proxy_template.IsEmpty()) {
3288 // Configure the global proxy object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003289 Handle<ObjectTemplateInfo> global_proxy_data =
Steve Blocka7e24c12009-10-30 11:49:00 +00003290 v8::Utils::OpenHandle(*global_proxy_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003291 if (!ConfigureApiObject(global_proxy, global_proxy_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003292
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003293 // Configure the global object.
Steve Blocka7e24c12009-10-30 11:49:00 +00003294 Handle<FunctionTemplateInfo> proxy_constructor(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003295 FunctionTemplateInfo::cast(global_proxy_data->constructor()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003296 if (!proxy_constructor->prototype_template()->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003297 Handle<ObjectTemplateInfo> global_object_data(
Steve Blocka7e24c12009-10-30 11:49:00 +00003298 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003299 if (!ConfigureApiObject(global_object, global_object_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00003300 }
3301 }
3302
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003303 SetObjectPrototype(global_proxy, global_object);
3304
3305 native_context()->set_initial_array_prototype(
3306 JSArray::cast(native_context()->array_function()->prototype()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003307 native_context()->set_array_buffer_map(
3308 native_context()->array_buffer_fun()->initial_map());
3309 native_context()->set_js_map_map(
3310 native_context()->js_map_fun()->initial_map());
3311 native_context()->set_js_set_map(
3312 native_context()->js_set_fun()->initial_map());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003313
Steve Blocka7e24c12009-10-30 11:49:00 +00003314 return true;
3315}
3316
3317
3318bool Genesis::ConfigureApiObject(Handle<JSObject> object,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003319 Handle<ObjectTemplateInfo> object_template) {
3320 DCHECK(!object_template.is_null());
3321 DCHECK(FunctionTemplateInfo::cast(object_template->constructor())
3322 ->IsTemplateFor(object->map()));;
Steve Blocka7e24c12009-10-30 11:49:00 +00003323
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003324 MaybeHandle<JSObject> maybe_obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003325 ApiNatives::InstantiateObject(object_template);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003326 Handle<JSObject> obj;
3327 if (!maybe_obj.ToHandle(&obj)) {
3328 DCHECK(isolate()->has_pending_exception());
Ben Murdoch257744e2011-11-30 15:57:28 +00003329 isolate()->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00003330 return false;
3331 }
3332 TransferObject(obj, object);
3333 return true;
3334}
3335
3336
3337void Genesis::TransferNamedProperties(Handle<JSObject> from,
3338 Handle<JSObject> to) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003339 // If JSObject::AddProperty asserts due to already existing property,
3340 // it is likely due to both global objects sharing property name(s).
3341 // Merging those two global objects is impossible.
3342 // The global template must not create properties that already exist
3343 // in the snapshotted global object.
Steve Blocka7e24c12009-10-30 11:49:00 +00003344 if (from->HasFastProperties()) {
3345 Handle<DescriptorArray> descs =
3346 Handle<DescriptorArray>(from->map()->instance_descriptors());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003347 for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
3348 PropertyDetails details = descs->GetDetails(i);
Steve Blocka7e24c12009-10-30 11:49:00 +00003349 switch (details.type()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003350 case DATA: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003351 HandleScope inner(isolate());
3352 Handle<Name> key = Handle<Name>(descs->GetKey(i));
3353 FieldIndex index = FieldIndex::ForDescriptor(from->map(), i);
3354 DCHECK(!descs->GetDetails(i).representation().IsDouble());
3355 Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
3356 isolate());
3357 JSObject::AddProperty(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003358 break;
3359 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003360 case DATA_CONSTANT: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003361 HandleScope inner(isolate());
3362 Handle<Name> key = Handle<Name>(descs->GetKey(i));
3363 Handle<Object> constant(descs->GetConstant(i), isolate());
3364 JSObject::AddProperty(to, key, constant, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003365 break;
3366 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003367 case ACCESSOR:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003368 UNREACHABLE();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003369 case ACCESSOR_CONSTANT: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003370 Handle<Name> key(descs->GetKey(i));
3371 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3372 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
Steve Blocka7e24c12009-10-30 11:49:00 +00003373 // If the property is already there we skip it
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003374 if (it.IsFound()) continue;
3375 HandleScope inner(isolate());
3376 DCHECK(!to->HasFastProperties());
Andrei Popescu31002712010-02-23 13:46:05 +00003377 // Add to dictionary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003378 Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003379 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
3380 PropertyCellType::kMutable);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003381 JSObject::SetNormalizedProperty(to, key, callbacks, d);
Steve Blocka7e24c12009-10-30 11:49:00 +00003382 break;
3383 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003384 }
3385 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003386 } else if (from->IsJSGlobalObject()) {
3387 Handle<GlobalDictionary> properties =
3388 Handle<GlobalDictionary>(from->global_dictionary());
3389 int capacity = properties->Capacity();
3390 for (int i = 0; i < capacity; i++) {
3391 Object* raw_key(properties->KeyAt(i));
3392 if (properties->IsKey(raw_key)) {
3393 DCHECK(raw_key->IsName());
3394 // If the property is already there we skip it.
3395 Handle<Name> key(Name::cast(raw_key));
3396 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3397 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3398 if (it.IsFound()) continue;
3399 // Set the property.
3400 DCHECK(properties->ValueAt(i)->IsPropertyCell());
3401 Handle<PropertyCell> cell(PropertyCell::cast(properties->ValueAt(i)));
3402 Handle<Object> value(cell->value(), isolate());
3403 if (value->IsTheHole()) continue;
3404 PropertyDetails details = cell->property_details();
3405 DCHECK_EQ(kData, details.kind());
3406 JSObject::AddProperty(to, key, value, details.attributes());
3407 }
3408 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003409 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003410 Handle<NameDictionary> properties =
3411 Handle<NameDictionary>(from->property_dictionary());
Steve Blocka7e24c12009-10-30 11:49:00 +00003412 int capacity = properties->Capacity();
3413 for (int i = 0; i < capacity; i++) {
3414 Object* raw_key(properties->KeyAt(i));
3415 if (properties->IsKey(raw_key)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003416 DCHECK(raw_key->IsName());
Steve Blocka7e24c12009-10-30 11:49:00 +00003417 // If the property is already there we skip it.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003418 Handle<Name> key(Name::cast(raw_key));
3419 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
3420 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
3421 if (it.IsFound()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00003422 // Set the property.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003423 Handle<Object> value = Handle<Object>(properties->ValueAt(i),
3424 isolate());
3425 DCHECK(!value->IsCell());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003426 DCHECK(!value->IsTheHole());
Steve Blocka7e24c12009-10-30 11:49:00 +00003427 PropertyDetails details = properties->DetailsAt(i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003428 DCHECK_EQ(kData, details.kind());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003429 JSObject::AddProperty(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00003430 }
3431 }
3432 }
3433}
3434
3435
3436void Genesis::TransferIndexedProperties(Handle<JSObject> from,
3437 Handle<JSObject> to) {
3438 // Cloning the elements array is sufficient.
3439 Handle<FixedArray> from_elements =
3440 Handle<FixedArray>(FixedArray::cast(from->elements()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003441 Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00003442 to->set_elements(*to_elements);
3443}
3444
3445
3446void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003447 HandleScope outer(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00003448
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003449 DCHECK(!from->IsJSArray());
3450 DCHECK(!to->IsJSArray());
Steve Blocka7e24c12009-10-30 11:49:00 +00003451
3452 TransferNamedProperties(from, to);
3453 TransferIndexedProperties(from, to);
3454
3455 // Transfer the prototype (new map is needed).
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003456 Handle<Object> proto(from->map()->prototype(), isolate());
3457 SetObjectPrototype(to, proto);
Steve Blocka7e24c12009-10-30 11:49:00 +00003458}
3459
3460
3461void Genesis::MakeFunctionInstancePrototypeWritable() {
Steve Block44f0eee2011-05-26 01:26:41 +01003462 // The maps with writable prototype are created in CreateEmptyFunction
3463 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
3464 // created with read-only prototype for JS builtins processing.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003465 DCHECK(!sloppy_function_map_writable_prototype_.is_null());
3466 DCHECK(!strict_function_map_writable_prototype_.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00003467
Steve Block44f0eee2011-05-26 01:26:41 +01003468 // Replace function instance maps to make prototype writable.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003469 native_context()->set_sloppy_function_map(
3470 *sloppy_function_map_writable_prototype_);
3471 native_context()->set_strict_function_map(
3472 *strict_function_map_writable_prototype_);
Steve Blocka7e24c12009-10-30 11:49:00 +00003473}
3474
3475
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003476class NoTrackDoubleFieldsForSerializerScope {
3477 public:
3478 explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003479 : flag_(FLAG_track_double_fields), enabled_(false) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003480 if (isolate->serializer_enabled()) {
3481 // Disable tracking double fields because heap numbers treated as
3482 // immutable by the serializer.
3483 FLAG_track_double_fields = false;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003484 enabled_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003485 }
3486 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003487
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003488 ~NoTrackDoubleFieldsForSerializerScope() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003489 if (enabled_) {
3490 FLAG_track_double_fields = flag_;
3491 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003492 }
3493
3494 private:
3495 bool flag_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003496 bool enabled_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003497};
3498
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003499Genesis::Genesis(Isolate* isolate,
3500 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003501 v8::Local<v8::ObjectTemplate> global_proxy_template,
3502 v8::ExtensionConfiguration* extensions,
Ben Murdoch097c5b22016-05-18 11:27:45 +01003503 GlobalContextType context_type)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003504 : isolate_(isolate), active_(isolate->bootstrapper()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003505 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
3506 result_ = Handle<Context>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +00003507 // Before creating the roots we must save the context and restore it
3508 // on all function exits.
Steve Block44f0eee2011-05-26 01:26:41 +01003509 SaveContext saved_context(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003510
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003511 // During genesis, the boilerplate for stack overflow won't work until the
3512 // environment has been at least partially initialized. Add a stack check
3513 // before entering JS code to catch overflow early.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003514 StackLimitCheck check(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003515 if (check.HasOverflowed()) {
3516 isolate->StackOverflow();
3517 return;
3518 }
3519
3520 // The deserializer needs to hook up references to the global proxy.
3521 // Create an uninitialized global proxy now if we don't have one
3522 // and initialize it later in CreateNewGlobals.
3523 Handle<JSGlobalProxy> global_proxy;
3524 if (!maybe_global_proxy.ToHandle(&global_proxy)) {
3525 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy();
3526 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003527
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003528 // We can only de-serialize a context if the isolate was initialized from
3529 // a snapshot. Otherwise we have to build the context from scratch.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003530 // Also create a context from scratch to expose natives, if required by flag.
3531 if (!isolate->initialized_from_snapshot() ||
3532 !Snapshot::NewContextFromSnapshot(isolate, global_proxy)
3533 .ToHandle(&native_context_)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003534 native_context_ = Handle<Context>();
3535 }
3536
3537 if (!native_context().is_null()) {
3538 AddToWeakNativeContextList(*native_context());
3539 isolate->set_context(*native_context());
Steve Block44f0eee2011-05-26 01:26:41 +01003540 isolate->counters()->contexts_created_by_snapshot()->Increment();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003541#if TRACE_MAPS
3542 if (FLAG_trace_maps) {
3543 Handle<JSFunction> object_fun = isolate->object_function();
3544 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n",
3545 reinterpret_cast<void*>(object_fun->initial_map()),
3546 object_fun->shared()->unique_id());
3547 Map::TraceAllTransitions(object_fun->initial_map());
3548 }
3549#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003550 Handle<JSGlobalObject> global_object =
3551 CreateNewGlobals(global_proxy_template, global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +00003552
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003553 HookUpGlobalProxy(global_object, global_proxy);
3554 HookUpGlobalObject(global_object);
Andrei Popescu402d9372010-02-26 13:31:12 +00003555
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003556 if (!ConfigureGlobalObjects(global_proxy_template)) return;
Andrei Popescu31002712010-02-23 13:46:05 +00003557 } else {
3558 // We get here if there was no context snapshot.
3559 CreateRoots();
Ben Murdoch257744e2011-11-30 15:57:28 +00003560 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01003561 CreateStrictModeFunctionMaps(empty_function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003562 CreateIteratorMaps();
3563 Handle<JSGlobalObject> global_object =
3564 CreateNewGlobals(global_proxy_template, global_proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003565 HookUpGlobalProxy(global_object, global_proxy);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003566 InitializeGlobal(global_object, empty_function, context_type);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01003567 InitializeNormalizedMapCaches();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003568
3569 if (!InstallNatives(context_type)) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00003570
Andrei Popescu31002712010-02-23 13:46:05 +00003571 MakeFunctionInstancePrototypeWritable();
Steve Blocka7e24c12009-10-30 11:49:00 +00003572
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003573 if (context_type != THIN_CONTEXT) {
3574 if (!InstallExtraNatives()) return;
3575 if (!ConfigureGlobalObjects(global_proxy_template)) return;
3576 }
Steve Block44f0eee2011-05-26 01:26:41 +01003577 isolate->counters()->contexts_created_from_scratch()->Increment();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003578 // Re-initialize the counter because it got incremented during snapshot
3579 // creation.
3580 isolate->native_context()->set_errors_thrown(Smi::FromInt(0));
Andrei Popescu31002712010-02-23 13:46:05 +00003581 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003582
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003583 // Install experimental natives. Do not include them into the
3584 // snapshot as we should be able to turn them off at runtime. Re-installing
3585 // them after they have already been deserialized would also fail.
3586 if (context_type == FULL_CONTEXT) {
3587 if (!isolate->serializer_enabled()) {
3588 InitializeExperimentalGlobal();
3589 if (!InstallExperimentalNatives()) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00003590
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003591 if (FLAG_experimental_extras) {
3592 if (!InstallExperimentalExtraNatives()) return;
3593 }
3594 }
3595 // The serializer cannot serialize typed arrays. Reset those typed arrays
3596 // for each new context.
3597 } else if (context_type == DEBUG_CONTEXT) {
3598 DCHECK(!isolate->serializer_enabled());
3599 InitializeExperimentalGlobal();
3600 if (!InstallDebuggerNatives()) return;
3601 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003602
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003603 ConfigureUtilsObject(context_type);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003604
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003605 // Check that the script context table is empty except for the 'this' binding.
3606 // We do not need script contexts for native scripts.
3607 if (!FLAG_global_var_shortcuts) {
3608 DCHECK_EQ(1, native_context()->script_context_table()->used());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003609 }
3610
3611 result_ = native_context();
Steve Blocka7e24c12009-10-30 11:49:00 +00003612}
3613
3614
3615// Support for thread preemption.
3616
3617// Reserve space for statics needing saving and restoring.
3618int Bootstrapper::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01003619 return sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003620}
3621
3622
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003623// Archive statics that are thread-local.
Steve Blocka7e24c12009-10-30 11:49:00 +00003624char* Bootstrapper::ArchiveState(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +01003625 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
3626 nesting_ = 0;
3627 return to + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003628}
3629
3630
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003631// Restore statics that are thread-local.
Steve Blocka7e24c12009-10-30 11:49:00 +00003632char* Bootstrapper::RestoreState(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +01003633 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
3634 return from + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00003635}
3636
3637
3638// Called when the top-level V8 mutex is destroyed.
3639void Bootstrapper::FreeThreadResources() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003640 DCHECK(!IsActive());
Steve Blocka7e24c12009-10-30 11:49:00 +00003641}
3642
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003643} // namespace internal
3644} // namespace v8