1 | // 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. |
4 | |
5 | #include "src/bootstrapper.h" |
6 | |
7 | #include "src/accessors.h" |
8 | #include "src/api-inl.h" |
9 | #include "src/api-natives.h" |
10 | #include "src/base/ieee754.h" |
11 | #include "src/compiler.h" |
12 | #include "src/counters.h" |
13 | #include "src/debug/debug.h" |
14 | #include "src/extensions/externalize-string-extension.h" |
15 | #include "src/extensions/free-buffer-extension.h" |
16 | #include "src/extensions/gc-extension.h" |
17 | #include "src/extensions/ignition-statistics-extension.h" |
18 | #include "src/extensions/statistics-extension.h" |
19 | #include "src/extensions/trigger-failure-extension.h" |
20 | #include "src/function-kind.h" |
21 | #include "src/heap/heap-inl.h" |
22 | #include "src/isolate-inl.h" |
23 | #include "src/math-random.h" |
24 | #include "src/microtask-queue.h" |
25 | #include "src/objects/api-callbacks.h" |
26 | #include "src/objects/arguments.h" |
27 | #include "src/objects/hash-table-inl.h" |
28 | #ifdef V8_INTL_SUPPORT |
29 | #include "src/objects/intl-objects.h" |
30 | #endif // V8_INTL_SUPPORT |
31 | #include "src/objects/js-array-buffer-inl.h" |
32 | #include "src/objects/js-array-inl.h" |
33 | #ifdef V8_INTL_SUPPORT |
34 | #include "src/objects/js-break-iterator.h" |
35 | #include "src/objects/js-collator.h" |
36 | #include "src/objects/js-date-time-format.h" |
37 | #include "src/objects/js-list-format.h" |
38 | #include "src/objects/js-locale.h" |
39 | #include "src/objects/js-number-format.h" |
40 | #include "src/objects/js-plural-rules.h" |
41 | #endif // V8_INTL_SUPPORT |
42 | #include "src/objects/js-regexp-string-iterator.h" |
43 | #include "src/objects/js-regexp.h" |
44 | #ifdef V8_INTL_SUPPORT |
45 | #include "src/objects/js-relative-time-format.h" |
46 | #include "src/objects/js-segment-iterator.h" |
47 | #include "src/objects/js-segmenter.h" |
48 | #endif // V8_INTL_SUPPORT |
49 | #include "src/objects/js-weak-refs.h" |
50 | #include "src/objects/property-cell.h" |
51 | #include "src/objects/slots-inl.h" |
52 | #include "src/objects/templates.h" |
53 | #include "src/snapshot/natives.h" |
54 | #include "src/snapshot/snapshot.h" |
55 | #include "src/wasm/wasm-js.h" |
56 | |
57 | namespace v8 { |
58 | namespace internal { |
59 | |
60 | void SourceCodeCache::Initialize(Isolate* isolate, bool create_heap_objects) { |
61 | cache_ = create_heap_objects ? ReadOnlyRoots(isolate).empty_fixed_array() |
62 | : FixedArray(); |
63 | } |
64 | |
65 | void SourceCodeCache::Iterate(RootVisitor* v) { |
66 | v->VisitRootPointer(Root::kExtensions, nullptr, FullObjectSlot(&cache_)); |
67 | } |
68 | |
69 | bool SourceCodeCache::Lookup(Isolate* isolate, Vector<const char> name, |
70 | Handle<SharedFunctionInfo>* handle) { |
71 | for (int i = 0; i < cache_->length(); i += 2) { |
72 | SeqOneByteString str = SeqOneByteString::cast(cache_->get(i)); |
73 | if (str->IsUtf8EqualTo(name)) { |
74 | *handle = Handle<SharedFunctionInfo>( |
75 | SharedFunctionInfo::cast(cache_->get(i + 1)), isolate); |
76 | return true; |
77 | } |
78 | } |
79 | return false; |
80 | } |
81 | |
82 | void SourceCodeCache::Add(Isolate* isolate, Vector<const char> name, |
83 | Handle<SharedFunctionInfo> shared) { |
84 | Factory* factory = isolate->factory(); |
85 | HandleScope scope(isolate); |
86 | int length = cache_->length(); |
87 | Handle<FixedArray> new_array = |
88 | factory->NewFixedArray(length + 2, AllocationType::kOld); |
89 | cache_->CopyTo(0, *new_array, 0, cache_->length()); |
90 | cache_ = *new_array; |
91 | Handle<String> str = |
92 | factory |
93 | ->NewStringFromOneByte(Vector<const uint8_t>::cast(name), |
94 | AllocationType::kOld) |
95 | .ToHandleChecked(); |
96 | DCHECK(!str.is_null()); |
97 | cache_->set(length, *str); |
98 | cache_->set(length + 1, *shared); |
99 | Script::cast(shared->script())->set_type(type_); |
100 | } |
101 | |
102 | Bootstrapper::Bootstrapper(Isolate* isolate) |
103 | : isolate_(isolate), |
104 | nesting_(0), |
105 | extensions_cache_(Script::TYPE_EXTENSION) {} |
106 | |
107 | Handle<String> Bootstrapper::GetNativeSource(NativeType type, int index) { |
108 | NativesExternalStringResource* resource = |
109 | new NativesExternalStringResource(type, index); |
110 | Handle<ExternalOneByteString> source_code = |
111 | isolate_->factory()->NewNativeSourceString(resource); |
112 | DCHECK(source_code->is_uncached()); |
113 | return source_code; |
114 | } |
115 | |
116 | void Bootstrapper::Initialize(bool create_heap_objects) { |
117 | extensions_cache_.Initialize(isolate_, create_heap_objects); |
118 | } |
119 | |
120 | |
121 | static const char* GCFunctionName() { |
122 | bool flag_given = |
123 | FLAG_expose_gc_as != nullptr && strlen(FLAG_expose_gc_as) != 0; |
124 | return flag_given ? FLAG_expose_gc_as : "gc" ; |
125 | } |
126 | |
127 | void Bootstrapper::InitializeOncePerProcess() { |
128 | v8::RegisterExtension(v8::base::make_unique<FreeBufferExtension>()); |
129 | v8::RegisterExtension(v8::base::make_unique<GCExtension>(GCFunctionName())); |
130 | v8::RegisterExtension(v8::base::make_unique<ExternalizeStringExtension>()); |
131 | v8::RegisterExtension(v8::base::make_unique<StatisticsExtension>()); |
132 | v8::RegisterExtension(v8::base::make_unique<TriggerFailureExtension>()); |
133 | v8::RegisterExtension(v8::base::make_unique<IgnitionStatisticsExtension>()); |
134 | } |
135 | |
136 | void Bootstrapper::TearDown() { |
137 | extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical |
138 | } |
139 | |
140 | class Genesis { |
141 | public: |
142 | Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
143 | v8::Local<v8::ObjectTemplate> global_proxy_template, |
144 | size_t context_snapshot_index, |
145 | v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer, |
146 | v8::MicrotaskQueue* microtask_queue); |
147 | Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
148 | v8::Local<v8::ObjectTemplate> global_proxy_template); |
149 | ~Genesis() = default; |
150 | |
151 | Isolate* isolate() const { return isolate_; } |
152 | Factory* factory() const { return isolate_->factory(); } |
153 | Builtins* builtins() const { return isolate_->builtins(); } |
154 | Heap* heap() const { return isolate_->heap(); } |
155 | |
156 | Handle<Context> result() { return result_; } |
157 | |
158 | Handle<JSGlobalProxy> global_proxy() { return global_proxy_; } |
159 | |
160 | private: |
161 | Handle<NativeContext> native_context() { return native_context_; } |
162 | |
163 | // Creates some basic objects. Used for creating a context from scratch. |
164 | void CreateRoots(); |
165 | // Creates the empty function. Used for creating a context from scratch. |
166 | Handle<JSFunction> CreateEmptyFunction(); |
167 | // Returns the %ThrowTypeError% intrinsic function. |
168 | // See ES#sec-%throwtypeerror% for details. |
169 | Handle<JSFunction> GetThrowTypeErrorIntrinsic(); |
170 | |
171 | void CreateSloppyModeFunctionMaps(Handle<JSFunction> empty); |
172 | void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); |
173 | void CreateObjectFunction(Handle<JSFunction> empty); |
174 | void CreateIteratorMaps(Handle<JSFunction> empty); |
175 | void CreateAsyncIteratorMaps(Handle<JSFunction> empty); |
176 | void CreateAsyncFunctionMaps(Handle<JSFunction> empty); |
177 | void CreateJSProxyMaps(); |
178 | |
179 | // Make the "arguments" and "caller" properties throw a TypeError on access. |
180 | void AddRestrictedFunctionProperties(Handle<JSFunction> empty); |
181 | |
182 | // Creates the global objects using the global proxy and the template passed |
183 | // in through the API. We call this regardless of whether we are building a |
184 | // context from scratch or using a deserialized one from the partial snapshot |
185 | // but in the latter case we don't use the objects it produces directly, as |
186 | // we have to use the deserialized ones that are linked together with the |
187 | // rest of the context snapshot. At the end we link the global proxy and the |
188 | // context to each other. |
189 | Handle<JSGlobalObject> CreateNewGlobals( |
190 | v8::Local<v8::ObjectTemplate> global_proxy_template, |
191 | Handle<JSGlobalProxy> global_proxy); |
192 | // Similarly, we want to use the global that has been created by the templates |
193 | // passed through the API. The global from the snapshot is detached from the |
194 | // other objects in the snapshot. |
195 | void HookUpGlobalObject(Handle<JSGlobalObject> global_object); |
196 | // Hooks the given global proxy into the context in the case we do not |
197 | // replace the global object from the deserialized native context. |
198 | void HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy); |
199 | // The native context has a ScriptContextTable that store declarative bindings |
200 | // made in script scopes. Add a "this" binding to that table pointing to the |
201 | // global proxy. |
202 | void InstallGlobalThisBinding(); |
203 | // New context initialization. Used for creating a context from scratch. |
204 | void InitializeGlobal(Handle<JSGlobalObject> global_object, |
205 | Handle<JSFunction> empty_function); |
206 | void InitializeExperimentalGlobal(); |
207 | void InitializeIteratorFunctions(); |
208 | void InitializeCallSiteBuiltins(); |
209 | // Depending on the situation, expose and/or get rid of the utils object. |
210 | void ConfigureUtilsObject(); |
211 | |
212 | #define DECLARE_FEATURE_INITIALIZATION(id, descr) \ |
213 | void InitializeGlobal_##id(); |
214 | |
215 | HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION) |
216 | HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION) |
217 | HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION) |
218 | #undef DECLARE_FEATURE_INITIALIZATION |
219 | |
220 | enum ArrayBufferKind { |
221 | ARRAY_BUFFER, |
222 | SHARED_ARRAY_BUFFER, |
223 | }; |
224 | Handle<JSFunction> CreateArrayBuffer(Handle<String> name, |
225 | ArrayBufferKind array_buffer_kind); |
226 | void InstallInternalPackedArrayFunction(Handle<JSObject> prototype, |
227 | const char* name); |
228 | void InstallInternalPackedArray(Handle<JSObject> target, const char* name); |
229 | bool InstallNatives(); |
230 | |
231 | Handle<JSFunction> InstallTypedArray(const char* name, |
232 | ElementsKind elements_kind); |
233 | bool InstallExtraNatives(); |
234 | void InitializeNormalizedMapCaches(); |
235 | |
236 | enum ExtensionTraversalState { |
237 | UNVISITED, VISITED, INSTALLED |
238 | }; |
239 | |
240 | class ExtensionStates { |
241 | public: |
242 | ExtensionStates(); |
243 | ExtensionTraversalState get_state(RegisteredExtension* extension); |
244 | void set_state(RegisteredExtension* extension, |
245 | ExtensionTraversalState state); |
246 | private: |
247 | base::HashMap map_; |
248 | DISALLOW_COPY_AND_ASSIGN(ExtensionStates); |
249 | }; |
250 | |
251 | // Used both for deserialized and from-scratch contexts to add the extensions |
252 | // provided. |
253 | static bool InstallExtensions(Isolate* isolate, |
254 | Handle<Context> native_context, |
255 | v8::ExtensionConfiguration* extensions); |
256 | static bool InstallAutoExtensions(Isolate* isolate, |
257 | ExtensionStates* extension_states); |
258 | static bool InstallRequestedExtensions(Isolate* isolate, |
259 | v8::ExtensionConfiguration* extensions, |
260 | ExtensionStates* extension_states); |
261 | static bool InstallExtension(Isolate* isolate, |
262 | const char* name, |
263 | ExtensionStates* extension_states); |
264 | static bool InstallExtension(Isolate* isolate, |
265 | v8::RegisteredExtension* current, |
266 | ExtensionStates* extension_states); |
267 | static bool InstallSpecialObjects(Isolate* isolate, |
268 | Handle<Context> native_context); |
269 | bool ConfigureApiObject(Handle<JSObject> object, |
270 | Handle<ObjectTemplateInfo> object_template); |
271 | bool ConfigureGlobalObjects( |
272 | v8::Local<v8::ObjectTemplate> global_proxy_template); |
273 | |
274 | // Migrates all properties from the 'from' object to the 'to' |
275 | // object and overrides the prototype in 'to' with the one from |
276 | // 'from'. |
277 | void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
278 | void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
279 | void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); |
280 | |
281 | static bool CompileExtension(Isolate* isolate, v8::Extension* extension); |
282 | |
283 | Isolate* isolate_; |
284 | Handle<Context> result_; |
285 | Handle<NativeContext> native_context_; |
286 | Handle<JSGlobalProxy> global_proxy_; |
287 | |
288 | // Temporary function maps needed only during bootstrapping. |
289 | Handle<Map> strict_function_with_home_object_map_; |
290 | Handle<Map> strict_function_with_name_and_home_object_map_; |
291 | |
292 | // %ThrowTypeError%. See ES#sec-%throwtypeerror% for details. |
293 | Handle<JSFunction> restricted_properties_thrower_; |
294 | |
295 | BootstrapperActive active_; |
296 | friend class Bootstrapper; |
297 | }; |
298 | |
299 | void Bootstrapper::Iterate(RootVisitor* v) { |
300 | extensions_cache_.Iterate(v); |
301 | v->Synchronize(VisitorSynchronization::kExtensions); |
302 | } |
303 | |
304 | Handle<Context> Bootstrapper::CreateEnvironment( |
305 | MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
306 | v8::Local<v8::ObjectTemplate> global_proxy_template, |
307 | v8::ExtensionConfiguration* extensions, size_t context_snapshot_index, |
308 | v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer, |
309 | v8::MicrotaskQueue* microtask_queue) { |
310 | HandleScope scope(isolate_); |
311 | Handle<Context> env; |
312 | { |
313 | Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template, |
314 | context_snapshot_index, embedder_fields_deserializer, |
315 | microtask_queue); |
316 | env = genesis.result(); |
317 | if (env.is_null() || !InstallExtensions(env, extensions)) { |
318 | return Handle<Context>(); |
319 | } |
320 | } |
321 | LogAllMaps(); |
322 | isolate_->heap()->NotifyBootstrapComplete(); |
323 | return scope.CloseAndEscape(env); |
324 | } |
325 | |
326 | Handle<JSGlobalProxy> Bootstrapper::NewRemoteContext( |
327 | MaybeHandle<JSGlobalProxy> maybe_global_proxy, |
328 | v8::Local<v8::ObjectTemplate> global_proxy_template) { |
329 | HandleScope scope(isolate_); |
330 | Handle<JSGlobalProxy> global_proxy; |
331 | { |
332 | Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template); |
333 | global_proxy = genesis.global_proxy(); |
334 | if (global_proxy.is_null()) return Handle<JSGlobalProxy>(); |
335 | } |
336 | LogAllMaps(); |
337 | return scope.CloseAndEscape(global_proxy); |
338 | } |
339 | |
340 | void Bootstrapper::LogAllMaps() { |
341 | if (!FLAG_trace_maps || isolate_->initialized_from_snapshot()) return; |
342 | // Log all created Map objects that are on the heap. For snapshots the Map |
343 | // logging happens during deserialization in order to avoid printing Maps |
344 | // multiple times during partial deserialization. |
345 | LOG(isolate_, LogAllMaps()); |
346 | } |
347 | |
348 | void Bootstrapper::DetachGlobal(Handle<Context> env) { |
349 | isolate_->counters()->errors_thrown_per_context()->AddSample( |
350 | env->GetErrorsThrown()); |
351 | |
352 | ReadOnlyRoots roots(isolate_); |
353 | Handle<JSGlobalProxy> global_proxy(env->global_proxy(), isolate_); |
354 | global_proxy->set_native_context(roots.null_value()); |
355 | JSObject::ForceSetPrototype(global_proxy, isolate_->factory()->null_value()); |
356 | global_proxy->map()->SetConstructor(roots.null_value()); |
357 | if (FLAG_track_detached_contexts) { |
358 | isolate_->AddDetachedContext(env); |
359 | } |
360 | |
361 | env->native_context()->set_microtask_queue(nullptr); |
362 | } |
363 | |
364 | namespace { |
365 | |
366 | V8_NOINLINE Handle<SharedFunctionInfo> SimpleCreateSharedFunctionInfo( |
367 | Isolate* isolate, Builtins::Name builtin_id, Handle<String> name, int len, |
368 | FunctionKind kind = FunctionKind::kNormalFunction) { |
369 | Handle<SharedFunctionInfo> shared = |
370 | isolate->factory()->NewSharedFunctionInfoForBuiltin(name, builtin_id, |
371 | kind); |
372 | shared->set_internal_formal_parameter_count(len); |
373 | shared->set_length(len); |
374 | return shared; |
375 | } |
376 | |
377 | V8_NOINLINE Handle<SharedFunctionInfo> SimpleCreateBuiltinSharedFunctionInfo( |
378 | Isolate* isolate, Builtins::Name builtin_id, Handle<String> name, int len) { |
379 | Handle<SharedFunctionInfo> shared = |
380 | isolate->factory()->NewSharedFunctionInfoForBuiltin(name, builtin_id, |
381 | kNormalFunction); |
382 | shared->set_internal_formal_parameter_count(len); |
383 | shared->set_length(len); |
384 | return shared; |
385 | } |
386 | |
387 | V8_NOINLINE Handle<JSFunction> CreateFunction( |
388 | Isolate* isolate, Handle<String> name, InstanceType type, int instance_size, |
389 | int inobject_properties, Handle<HeapObject> prototype, |
390 | Builtins::Name builtin_id) { |
391 | Handle<JSFunction> result; |
392 | |
393 | NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype( |
394 | name, prototype, type, instance_size, inobject_properties, builtin_id, |
395 | IMMUTABLE); |
396 | |
397 | result = isolate->factory()->NewFunction(args); |
398 | // Make the JSFunction's prototype object fast. |
399 | JSObject::MakePrototypesFast(handle(result->prototype(), isolate), |
400 | kStartAtReceiver, isolate); |
401 | |
402 | // Make the resulting JSFunction object fast. |
403 | JSObject::MakePrototypesFast(result, kStartAtReceiver, isolate); |
404 | result->shared()->set_native(true); |
405 | return result; |
406 | } |
407 | |
408 | V8_NOINLINE Handle<JSFunction> CreateFunction( |
409 | Isolate* isolate, const char* name, InstanceType type, int instance_size, |
410 | int inobject_properties, Handle<HeapObject> prototype, |
411 | Builtins::Name builtin_id) { |
412 | return CreateFunction( |
413 | isolate, isolate->factory()->InternalizeUtf8String(name), type, |
414 | instance_size, inobject_properties, prototype, builtin_id); |
415 | } |
416 | |
417 | V8_NOINLINE Handle<JSFunction> InstallFunction( |
418 | Isolate* isolate, Handle<JSObject> target, Handle<String> name, |
419 | InstanceType type, int instance_size, int inobject_properties, |
420 | Handle<HeapObject> prototype, Builtins::Name call) { |
421 | Handle<JSFunction> function = CreateFunction( |
422 | isolate, name, type, instance_size, inobject_properties, prototype, call); |
423 | JSObject::AddProperty(isolate, target, name, function, DONT_ENUM); |
424 | return function; |
425 | } |
426 | |
427 | V8_NOINLINE Handle<JSFunction> InstallFunction( |
428 | Isolate* isolate, Handle<JSObject> target, const char* name, |
429 | InstanceType type, int instance_size, int inobject_properties, |
430 | Handle<HeapObject> prototype, Builtins::Name call) { |
431 | return InstallFunction(isolate, target, |
432 | isolate->factory()->InternalizeUtf8String(name), type, |
433 | instance_size, inobject_properties, prototype, call); |
434 | } |
435 | |
436 | V8_NOINLINE Handle<JSFunction> SimpleCreateFunction(Isolate* isolate, |
437 | Handle<String> name, |
438 | Builtins::Name call, |
439 | int len, bool adapt) { |
440 | NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithoutPrototype( |
441 | name, call, LanguageMode::kStrict); |
442 | Handle<JSFunction> fun = isolate->factory()->NewFunction(args); |
443 | // Make the resulting JSFunction object fast. |
444 | JSObject::MakePrototypesFast(fun, kStartAtReceiver, isolate); |
445 | fun->shared()->set_native(true); |
446 | |
447 | if (adapt) { |
448 | fun->shared()->set_internal_formal_parameter_count(len); |
449 | } else { |
450 | fun->shared()->DontAdaptArguments(); |
451 | } |
452 | fun->shared()->set_length(len); |
453 | return fun; |
454 | } |
455 | |
456 | V8_NOINLINE Handle<JSFunction> InstallFunctionWithBuiltinId( |
457 | Isolate* isolate, Handle<JSObject> base, const char* name, |
458 | Builtins::Name call, int len, bool adapt) { |
459 | Handle<String> internalized_name = |
460 | isolate->factory()->InternalizeUtf8String(name); |
461 | Handle<JSFunction> fun = |
462 | SimpleCreateFunction(isolate, internalized_name, call, len, adapt); |
463 | JSObject::AddProperty(isolate, base, internalized_name, fun, DONT_ENUM); |
464 | return fun; |
465 | } |
466 | |
467 | V8_NOINLINE Handle<JSFunction> SimpleInstallFunction( |
468 | Isolate* isolate, Handle<JSObject> base, const char* name, |
469 | Builtins::Name call, int len, bool adapt, |
470 | PropertyAttributes attrs = DONT_ENUM) { |
471 | // Although function name does not have to be internalized the property name |
472 | // will be internalized during property addition anyway, so do it here now. |
473 | Handle<String> internalized_name = |
474 | isolate->factory()->InternalizeUtf8String(name); |
475 | Handle<JSFunction> fun = |
476 | SimpleCreateFunction(isolate, internalized_name, call, len, adapt); |
477 | JSObject::AddProperty(isolate, base, internalized_name, fun, attrs); |
478 | return fun; |
479 | } |
480 | |
481 | V8_NOINLINE Handle<JSFunction> InstallFunctionAtSymbol( |
482 | Isolate* isolate, Handle<JSObject> base, Handle<Symbol> symbol, |
483 | const char* symbol_string, Builtins::Name call, int len, bool adapt, |
484 | PropertyAttributes attrs = DONT_ENUM) { |
485 | Handle<String> internalized_symbol = |
486 | isolate->factory()->InternalizeUtf8String(symbol_string); |
487 | Handle<JSFunction> fun = |
488 | SimpleCreateFunction(isolate, internalized_symbol, call, len, adapt); |
489 | JSObject::AddProperty(isolate, base, symbol, fun, attrs); |
490 | return fun; |
491 | } |
492 | |
493 | V8_NOINLINE void SimpleInstallGetterSetter(Isolate* isolate, |
494 | Handle<JSObject> base, |
495 | Handle<String> name, |
496 | Builtins::Name call_getter, |
497 | Builtins::Name call_setter) { |
498 | Handle<String> getter_name = |
499 | Name::ToFunctionName(isolate, name, isolate->factory()->get_string()) |
500 | .ToHandleChecked(); |
501 | Handle<JSFunction> getter = |
502 | SimpleCreateFunction(isolate, getter_name, call_getter, 0, true); |
503 | |
504 | Handle<String> setter_name = |
505 | Name::ToFunctionName(isolate, name, isolate->factory()->set_string()) |
506 | .ToHandleChecked(); |
507 | Handle<JSFunction> setter = |
508 | SimpleCreateFunction(isolate, setter_name, call_setter, 1, true); |
509 | |
510 | JSObject::DefineAccessor(base, name, getter, setter, DONT_ENUM).Check(); |
511 | } |
512 | |
513 | void SimpleInstallGetterSetter(Isolate* isolate, Handle<JSObject> base, |
514 | const char* name, Builtins::Name call_getter, |
515 | Builtins::Name call_setter) { |
516 | SimpleInstallGetterSetter(isolate, base, |
517 | isolate->factory()->InternalizeUtf8String(name), |
518 | call_getter, call_setter); |
519 | } |
520 | |
521 | V8_NOINLINE Handle<JSFunction> SimpleInstallGetter( |
522 | Isolate* isolate, Handle<JSObject> base, Handle<Name> name, |
523 | Handle<Name> property_name, Builtins::Name call, bool adapt) { |
524 | Handle<String> getter_name = |
525 | Name::ToFunctionName(isolate, name, isolate->factory()->get_string()) |
526 | .ToHandleChecked(); |
527 | Handle<JSFunction> getter = |
528 | SimpleCreateFunction(isolate, getter_name, call, 0, adapt); |
529 | |
530 | Handle<Object> setter = isolate->factory()->undefined_value(); |
531 | |
532 | JSObject::DefineAccessor(base, property_name, getter, setter, DONT_ENUM) |
533 | .Check(); |
534 | |
535 | return getter; |
536 | } |
537 | |
538 | V8_NOINLINE Handle<JSFunction> SimpleInstallGetter(Isolate* isolate, |
539 | Handle<JSObject> base, |
540 | Handle<Name> name, |
541 | Builtins::Name call, |
542 | bool adapt) { |
543 | return SimpleInstallGetter(isolate, base, name, name, call, adapt); |
544 | } |
545 | |
546 | V8_NOINLINE void InstallConstant(Isolate* isolate, Handle<JSObject> holder, |
547 | const char* name, Handle<Object> value) { |
548 | JSObject::AddProperty( |
549 | isolate, holder, isolate->factory()->InternalizeUtf8String(name), value, |
550 | static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY)); |
551 | } |
552 | |
553 | V8_NOINLINE void InstallTrueValuedProperty(Isolate* isolate, |
554 | Handle<JSObject> holder, |
555 | const char* name) { |
556 | JSObject::AddProperty(isolate, holder, |
557 | isolate->factory()->InternalizeUtf8String(name), |
558 | isolate->factory()->true_value(), NONE); |
559 | } |
560 | |
561 | V8_NOINLINE void InstallSpeciesGetter(Isolate* isolate, |
562 | Handle<JSFunction> constructor) { |
563 | Factory* factory = isolate->factory(); |
564 | // TODO(adamk): We should be able to share a SharedFunctionInfo |
565 | // between all these JSFunctins. |
566 | SimpleInstallGetter(isolate, constructor, factory->symbol_species_string(), |
567 | factory->species_symbol(), Builtins::kReturnReceiver, |
568 | true); |
569 | } |
570 | |
571 | V8_NOINLINE void InstallToStringTag(Isolate* isolate, Handle<JSObject> holder, |
572 | Handle<String> value) { |
573 | JSObject::AddProperty(isolate, holder, |
574 | isolate->factory()->to_string_tag_symbol(), value, |
575 | static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); |
576 | } |
577 | |
578 | void InstallToStringTag(Isolate* isolate, Handle<JSObject> holder, |
579 | const char* value) { |
580 | InstallToStringTag(isolate, holder, |
581 | isolate->factory()->InternalizeUtf8String(value)); |
582 | } |
583 | |
584 | } // namespace |
585 | |
586 | Handle<JSFunction> Genesis::CreateEmptyFunction() { |
587 | // Allocate the function map first and then patch the prototype later. |
588 | Handle<Map> empty_function_map = factory()->CreateSloppyFunctionMap( |
589 | FUNCTION_WITHOUT_PROTOTYPE, MaybeHandle<JSFunction>()); |
590 | empty_function_map->set_is_prototype_map(true); |
591 | DCHECK(!empty_function_map->is_dictionary_map()); |
592 | |
593 | // Allocate ScopeInfo for the empty function. |
594 | Handle<ScopeInfo> scope_info = ScopeInfo::CreateForEmptyFunction(isolate()); |
595 | |
596 | // Allocate the empty function as the prototype for function according to |
597 | // ES#sec-properties-of-the-function-prototype-object |
598 | NewFunctionArgs args = NewFunctionArgs::ForBuiltin( |
599 | factory()->empty_string(), empty_function_map, Builtins::kEmptyFunction); |
600 | Handle<JSFunction> empty_function = factory()->NewFunction(args); |
601 | native_context()->set_empty_function(*empty_function); |
602 | |
603 | // --- E m p t y --- |
604 | Handle<String> source = factory()->NewStringFromStaticChars("() {}" ); |
605 | Handle<Script> script = factory()->NewScript(source); |
606 | script->set_type(Script::TYPE_NATIVE); |
607 | Handle<WeakFixedArray> infos = factory()->NewWeakFixedArray(2); |
608 | script->set_shared_function_infos(*infos); |
609 | empty_function->shared()->set_scope_info(*scope_info); |
610 | empty_function->shared()->DontAdaptArguments(); |
611 | SharedFunctionInfo::SetScript(handle(empty_function->shared(), isolate()), |
612 | script, 1); |
613 | |
614 | return empty_function; |
615 | } |
616 | |
617 | void Genesis::CreateSloppyModeFunctionMaps(Handle<JSFunction> empty) { |
618 | Factory* factory = isolate_->factory(); |
619 | Handle<Map> map; |
620 | |
621 | // |
622 | // Allocate maps for sloppy functions without prototype. |
623 | // |
624 | map = factory->CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty); |
625 | native_context()->set_sloppy_function_without_prototype_map(*map); |
626 | |
627 | // |
628 | // Allocate maps for sloppy functions with readonly prototype. |
629 | // |
630 | map = |
631 | factory->CreateSloppyFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty); |
632 | native_context()->set_sloppy_function_with_readonly_prototype_map(*map); |
633 | |
634 | // |
635 | // Allocate maps for sloppy functions with writable prototype. |
636 | // |
637 | map = factory->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, |
638 | empty); |
639 | native_context()->set_sloppy_function_map(*map); |
640 | |
641 | map = factory->CreateSloppyFunctionMap( |
642 | FUNCTION_WITH_NAME_AND_WRITEABLE_PROTOTYPE, empty); |
643 | native_context()->set_sloppy_function_with_name_map(*map); |
644 | } |
645 | |
646 | Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic() { |
647 | if (!restricted_properties_thrower_.is_null()) { |
648 | return restricted_properties_thrower_; |
649 | } |
650 | Handle<String> name = factory()->empty_string(); |
651 | NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithoutPrototype( |
652 | name, Builtins::kStrictPoisonPillThrower, i::LanguageMode::kStrict); |
653 | Handle<JSFunction> function = factory()->NewFunction(args); |
654 | function->shared()->DontAdaptArguments(); |
655 | |
656 | // %ThrowTypeError% must not have a name property. |
657 | if (JSReceiver::DeleteProperty(function, factory()->name_string()) |
658 | .IsNothing()) { |
659 | DCHECK(false); |
660 | } |
661 | |
662 | // length needs to be non configurable. |
663 | Handle<Object> value(Smi::FromInt(function->length()), isolate()); |
664 | JSObject::SetOwnPropertyIgnoreAttributes( |
665 | function, factory()->length_string(), value, |
666 | static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY)) |
667 | .Assert(); |
668 | |
669 | if (JSObject::PreventExtensions(function, kThrowOnError).IsNothing()) { |
670 | DCHECK(false); |
671 | } |
672 | |
673 | JSObject::MigrateSlowToFast(function, 0, "Bootstrapping" ); |
674 | |
675 | restricted_properties_thrower_ = function; |
676 | return function; |
677 | } |
678 | |
679 | void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { |
680 | Factory* factory = isolate_->factory(); |
681 | Handle<Map> map; |
682 | |
683 | // |
684 | // Allocate maps for strict functions without prototype. |
685 | // |
686 | map = factory->CreateStrictFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty); |
687 | native_context()->set_strict_function_without_prototype_map(*map); |
688 | |
689 | map = factory->CreateStrictFunctionMap(METHOD_WITH_NAME, empty); |
690 | native_context()->set_method_with_name_map(*map); |
691 | |
692 | map = factory->CreateStrictFunctionMap(METHOD_WITH_HOME_OBJECT, empty); |
693 | native_context()->set_method_with_home_object_map(*map); |
694 | |
695 | map = |
696 | factory->CreateStrictFunctionMap(METHOD_WITH_NAME_AND_HOME_OBJECT, empty); |
697 | native_context()->set_method_with_name_and_home_object_map(*map); |
698 | |
699 | // |
700 | // Allocate maps for strict functions with writable prototype. |
701 | // |
702 | map = factory->CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, |
703 | empty); |
704 | native_context()->set_strict_function_map(*map); |
705 | |
706 | map = factory->CreateStrictFunctionMap( |
707 | FUNCTION_WITH_NAME_AND_WRITEABLE_PROTOTYPE, empty); |
708 | native_context()->set_strict_function_with_name_map(*map); |
709 | |
710 | strict_function_with_home_object_map_ = factory->CreateStrictFunctionMap( |
711 | FUNCTION_WITH_HOME_OBJECT_AND_WRITEABLE_PROTOTYPE, empty); |
712 | strict_function_with_name_and_home_object_map_ = |
713 | factory->CreateStrictFunctionMap( |
714 | FUNCTION_WITH_NAME_AND_HOME_OBJECT_AND_WRITEABLE_PROTOTYPE, empty); |
715 | |
716 | // |
717 | // Allocate maps for strict functions with readonly prototype. |
718 | // |
719 | map = |
720 | factory->CreateStrictFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty); |
721 | native_context()->set_strict_function_with_readonly_prototype_map(*map); |
722 | |
723 | // |
724 | // Allocate map for class functions. |
725 | // |
726 | map = factory->CreateClassFunctionMap(empty); |
727 | native_context()->set_class_function_map(*map); |
728 | |
729 | // Now that the strict mode function map is available, set up the |
730 | // restricted "arguments" and "caller" getters. |
731 | AddRestrictedFunctionProperties(empty); |
732 | } |
733 | |
734 | void Genesis::CreateObjectFunction(Handle<JSFunction> empty_function) { |
735 | Factory* factory = isolate_->factory(); |
736 | |
737 | // --- O b j e c t --- |
738 | int inobject_properties = JSObject::kInitialGlobalObjectUnusedPropertiesCount; |
739 | int instance_size = JSObject::kHeaderSize + kTaggedSize * inobject_properties; |
740 | |
741 | Handle<JSFunction> object_fun = CreateFunction( |
742 | isolate_, factory->Object_string(), JS_OBJECT_TYPE, instance_size, |
743 | inobject_properties, factory->null_value(), Builtins::kObjectConstructor); |
744 | object_fun->shared()->set_length(1); |
745 | object_fun->shared()->DontAdaptArguments(); |
746 | native_context()->set_object_function(*object_fun); |
747 | |
748 | { |
749 | // Finish setting up Object function's initial map. |
750 | Map initial_map = object_fun->initial_map(); |
751 | initial_map->set_elements_kind(HOLEY_ELEMENTS); |
752 | } |
753 | |
754 | // Allocate a new prototype for the object function. |
755 | Handle<JSObject> object_function_prototype = |
756 | factory->NewFunctionPrototype(object_fun); |
757 | |
758 | Handle<Map> map = |
759 | Map::Copy(isolate(), handle(object_function_prototype->map(), isolate()), |
760 | "EmptyObjectPrototype" ); |
761 | map->set_is_prototype_map(true); |
762 | // Ban re-setting Object.prototype.__proto__ to prevent Proxy security bug |
763 | map->set_is_immutable_proto(true); |
764 | object_function_prototype->set_map(*map); |
765 | |
766 | // Complete setting up empty function. |
767 | { |
768 | Handle<Map> empty_function_map(empty_function->map(), isolate_); |
769 | Map::SetPrototype(isolate(), empty_function_map, object_function_prototype); |
770 | } |
771 | |
772 | native_context()->set_initial_object_prototype(*object_function_prototype); |
773 | JSFunction::SetPrototype(object_fun, object_function_prototype); |
774 | |
775 | { |
776 | // Set up slow map for Object.create(null) instances without in-object |
777 | // properties. |
778 | Handle<Map> map(object_fun->initial_map(), isolate_); |
779 | map = Map::CopyInitialMapNormalized(isolate(), map); |
780 | Map::SetPrototype(isolate(), map, factory->null_value()); |
781 | native_context()->set_slow_object_with_null_prototype_map(*map); |
782 | |
783 | // Set up slow map for literals with too many properties. |
784 | map = Map::Copy(isolate(), map, "slow_object_with_object_prototype_map" ); |
785 | Map::SetPrototype(isolate(), map, object_function_prototype); |
786 | native_context()->set_slow_object_with_object_prototype_map(*map); |
787 | } |
788 | } |
789 | |
790 | namespace { |
791 | |
792 | Handle<Map> CreateNonConstructorMap(Isolate* isolate, Handle<Map> source_map, |
793 | Handle<JSObject> prototype, |
794 | const char* reason) { |
795 | Handle<Map> map = Map::Copy(isolate, source_map, reason); |
796 | // Ensure the resulting map has prototype slot (it is necessary for storing |
797 | // inital map even when the prototype property is not required). |
798 | if (!map->has_prototype_slot()) { |
799 | // Re-set the unused property fields after changing the instance size. |
800 | // TODO(ulan): Do not change instance size after map creation. |
801 | int unused_property_fields = map->UnusedPropertyFields(); |
802 | map->set_instance_size(map->instance_size() + kTaggedSize); |
803 | // The prototype slot shifts the in-object properties area by one slot. |
804 | map->SetInObjectPropertiesStartInWords( |
805 | map->GetInObjectPropertiesStartInWords() + 1); |
806 | map->set_has_prototype_slot(true); |
807 | map->SetInObjectUnusedPropertyFields(unused_property_fields); |
808 | } |
809 | map->set_is_constructor(false); |
810 | Map::SetPrototype(isolate, map, prototype); |
811 | return map; |
812 | } |
813 | |
814 | } // namespace |
815 | |
816 | void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) { |
817 | // Create iterator-related meta-objects. |
818 | Handle<JSObject> iterator_prototype = factory()->NewJSObject( |
819 | isolate()->object_function(), AllocationType::kOld); |
820 | |
821 | InstallFunctionAtSymbol(isolate(), iterator_prototype, |
822 | factory()->iterator_symbol(), "[Symbol.iterator]" , |
823 | Builtins::kReturnReceiver, 0, true); |
824 | native_context()->set_initial_iterator_prototype(*iterator_prototype); |
825 | |
826 | Handle<JSObject> generator_object_prototype = factory()->NewJSObject( |
827 | isolate()->object_function(), AllocationType::kOld); |
828 | native_context()->set_initial_generator_prototype( |
829 | *generator_object_prototype); |
830 | JSObject::ForceSetPrototype(generator_object_prototype, iterator_prototype); |
831 | Handle<JSObject> generator_function_prototype = factory()->NewJSObject( |
832 | isolate()->object_function(), AllocationType::kOld); |
833 | JSObject::ForceSetPrototype(generator_function_prototype, empty); |
834 | |
835 | InstallToStringTag(isolate(), generator_function_prototype, |
836 | "GeneratorFunction" ); |
837 | JSObject::AddProperty(isolate(), generator_function_prototype, |
838 | factory()->prototype_string(), |
839 | generator_object_prototype, |
840 | static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); |
841 | |
842 | JSObject::AddProperty(isolate(), generator_object_prototype, |
843 | factory()->constructor_string(), |
844 | generator_function_prototype, |
845 | static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); |
846 | InstallToStringTag(isolate(), generator_object_prototype, "Generator" ); |
847 | SimpleInstallFunction(isolate(), generator_object_prototype, "next" , |
848 | Builtins::kGeneratorPrototypeNext, 1, false); |
849 | SimpleInstallFunction(isolate(), generator_object_prototype, "return" , |
850 | Builtins::kGeneratorPrototypeReturn, 1, false); |
851 | SimpleInstallFunction(isolate(), generator_object_prototype, "throw" , |
852 | Builtins::kGeneratorPrototypeThrow, 1, false); |
853 | |
854 | // Internal version of generator_prototype_next, flagged as non-native such |
855 | // that it doesn't show up in Error traces. |
856 | Handle<JSFunction> generator_next_internal = |
857 | SimpleCreateFunction(isolate(), factory()->next_string(), |
858 | Builtins::kGeneratorPrototypeNext, 1, false); |
859 | generator_next_internal->shared()->set_native(false); |
860 | native_context()->set_generator_next_internal(*generator_next_internal); |
861 | |
862 | // Create maps for generator functions and their prototypes. Store those |
863 | // maps in the native context. The "prototype" property descriptor is |
864 | // writable, non-enumerable, and non-configurable (as per ES6 draft |
865 | // 04-14-15, section 25.2.4.3). |
866 | // Generator functions do not have "caller" or "arguments" accessors. |
867 | Handle<Map> map; |
868 | map = CreateNonConstructorMap(isolate(), isolate()->strict_function_map(), |
869 | generator_function_prototype, |
870 | "GeneratorFunction" ); |
871 | native_context()->set_generator_function_map(*map); |
872 | |
873 | map = CreateNonConstructorMap( |
874 | isolate(), isolate()->strict_function_with_name_map(), |
875 | generator_function_prototype, "GeneratorFunction with name" ); |
876 | native_context()->set_generator_function_with_name_map(*map); |
877 | |
878 | map = CreateNonConstructorMap( |
879 | isolate(), strict_function_with_home_object_map_, |
880 | generator_function_prototype, "GeneratorFunction with home object" ); |
881 | native_context()->set_generator_function_with_home_object_map(*map); |
882 | |
883 | map = CreateNonConstructorMap(isolate(), |
884 | strict_function_with_name_and_home_object_map_, |
885 | generator_function_prototype, |
886 | "GeneratorFunction with name and home object" ); |
887 | native_context()->set_generator_function_with_name_and_home_object_map(*map); |
888 | |
889 | Handle<JSFunction> object_function(native_context()->object_function(), |
890 | isolate()); |
891 | Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0); |
892 | Map::SetPrototype(isolate(), generator_object_prototype_map, |
893 | generator_object_prototype); |
894 | native_context()->set_generator_object_prototype_map( |
895 | *generator_object_prototype_map); |
896 | } |
897 | |
898 | void Genesis::CreateAsyncIteratorMaps(Handle<JSFunction> empty) { |
899 | // %AsyncIteratorPrototype% |
900 | // proposal-async-iteration/#sec-asynciteratorprototype |
901 | Handle<JSObject> async_iterator_prototype = factory()->NewJSObject( |
902 | isolate()->object_function(), AllocationType::kOld); |
903 | |
904 | InstallFunctionAtSymbol( |
905 | isolate(), async_iterator_prototype, factory()->async_iterator_symbol(), |
906 | "[Symbol.asyncIterator]" , Builtins::kReturnReceiver, 0, true); |
907 | |
908 | // %AsyncFromSyncIteratorPrototype% |
909 | // proposal-async-iteration/#sec-%asyncfromsynciteratorprototype%-object |
910 | Handle<JSObject> async_from_sync_iterator_prototype = factory()->NewJSObject( |
911 | isolate()->object_function(), AllocationType::kOld); |
912 | SimpleInstallFunction(isolate(), async_from_sync_iterator_prototype, "next" , |
913 | Builtins::kAsyncFromSyncIteratorPrototypeNext, 1, true); |
914 | SimpleInstallFunction(isolate(), async_from_sync_iterator_prototype, "return" , |
915 | Builtins::kAsyncFromSyncIteratorPrototypeReturn, 1, |
916 | true); |
917 | SimpleInstallFunction(isolate(), async_from_sync_iterator_prototype, "throw" , |
918 | Builtins::kAsyncFromSyncIteratorPrototypeThrow, 1, |
919 | true); |
920 | |
921 | InstallToStringTag(isolate(), async_from_sync_iterator_prototype, |
922 | "Async-from-Sync Iterator" ); |
923 | |
924 | JSObject::ForceSetPrototype(async_from_sync_iterator_prototype, |
925 | async_iterator_prototype); |
926 | |
927 | Handle<Map> async_from_sync_iterator_map = factory()->NewMap( |
928 | JS_ASYNC_FROM_SYNC_ITERATOR_TYPE, JSAsyncFromSyncIterator::kSize); |
929 | Map::SetPrototype(isolate(), async_from_sync_iterator_map, |
930 | async_from_sync_iterator_prototype); |
931 | native_context()->set_async_from_sync_iterator_map( |
932 | *async_from_sync_iterator_map); |
933 | |
934 | // Async Generators |
935 | Handle<JSObject> async_generator_object_prototype = factory()->NewJSObject( |
936 | isolate()->object_function(), AllocationType::kOld); |
937 | Handle<JSObject> async_generator_function_prototype = factory()->NewJSObject( |
938 | isolate()->object_function(), AllocationType::kOld); |
939 | |
940 | // %AsyncGenerator% / %AsyncGeneratorFunction%.prototype |
941 | JSObject::ForceSetPrototype(async_generator_function_prototype, empty); |
942 | |
943 | // The value of AsyncGeneratorFunction.prototype.prototype is the |
944 | // %AsyncGeneratorPrototype% intrinsic object. |
945 | // This property has the attributes |
946 | // { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. |
947 | JSObject::AddProperty(isolate(), async_generator_function_prototype, |
948 | factory()->prototype_string(), |
949 | async_generator_object_prototype, |
950 | static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); |
951 | JSObject::AddProperty(isolate(), async_generator_object_prototype, |
952 | factory()->constructor_string(), |
953 | async_generator_function_prototype, |
954 | static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); |
955 | InstallToStringTag(isolate(), async_generator_function_prototype, |
956 | "AsyncGeneratorFunction" ); |
957 | |
958 | // %AsyncGeneratorPrototype% |
959 | JSObject::ForceSetPrototype(async_generator_object_prototype, |
960 | async_iterator_prototype); |
961 | native_context()->set_initial_async_generator_prototype( |
962 | *async_generator_object_prototype); |
963 | |
964 | InstallToStringTag(isolate(), async_generator_object_prototype, |
965 | "AsyncGenerator" ); |
966 | SimpleInstallFunction(isolate(), async_generator_object_prototype, "next" , |
967 | Builtins::kAsyncGeneratorPrototypeNext, 1, false); |
968 | SimpleInstallFunction(isolate(), async_generator_object_prototype, "return" , |
969 | Builtins::kAsyncGeneratorPrototypeReturn, 1, false); |
970 | SimpleInstallFunction(isolate(), async_generator_object_prototype, "throw" , |
971 | Builtins::kAsyncGeneratorPrototypeThrow, 1, false); |
972 | |
973 | // Create maps for generator functions and their prototypes. Store those |
974 | // maps in the native context. The "prototype" property descriptor is |
975 | // writable, non-enumerable, and non-configurable (as per ES6 draft |
976 | // 04-14-15, section 25.2.4.3). |
977 | // Async Generator functions do not have "caller" or "arguments" accessors. |
978 | Handle<Map> map; |
979 | map = CreateNonConstructorMap(isolate(), isolate()->strict_function_map(), |
980 | async_generator_function_prototype, |
981 | "AsyncGeneratorFunction" ); |
982 | native_context()->set_async_generator_function_map(*map); |
983 | |
984 | map = CreateNonConstructorMap( |
985 | isolate(), isolate()->strict_function_with_name_map(), |
986 | async_generator_function_prototype, "AsyncGeneratorFunction with name" ); |
987 | native_context()->set_async_generator_function_with_name_map(*map); |
988 | |
989 | map = |
990 | CreateNonConstructorMap(isolate(), strict_function_with_home_object_map_, |
991 | async_generator_function_prototype, |
992 | "AsyncGeneratorFunction with home object" ); |
993 | native_context()->set_async_generator_function_with_home_object_map(*map); |
994 | |
995 | map = CreateNonConstructorMap( |
996 | isolate(), strict_function_with_name_and_home_object_map_, |
997 | async_generator_function_prototype, |
998 | "AsyncGeneratorFunction with name and home object" ); |
999 | native_context()->set_async_generator_function_with_name_and_home_object_map( |
1000 | *map); |
1001 | |
1002 | Handle<JSFunction> object_function(native_context()->object_function(), |
1003 | isolate()); |
1004 | Handle<Map> async_generator_object_prototype_map = Map::Create(isolate(), 0); |
1005 | Map::SetPrototype(isolate(), async_generator_object_prototype_map, |
1006 | async_generator_object_prototype); |
1007 | native_context()->set_async_generator_object_prototype_map( |
1008 | *async_generator_object_prototype_map); |
1009 | } |
1010 | |
1011 | void Genesis::CreateAsyncFunctionMaps(Handle<JSFunction> empty) { |
1012 | // %AsyncFunctionPrototype% intrinsic |
1013 | Handle<JSObject> async_function_prototype = factory()->NewJSObject( |
1014 | isolate()->object_function(), AllocationType::kOld); |
1015 | JSObject::ForceSetPrototype(async_function_prototype, empty); |
1016 | |
1017 | InstallToStringTag(isolate(), async_function_prototype, "AsyncFunction" ); |
1018 | |
1019 | Handle<Map> map = |
1020 | Map::Copy(isolate(), isolate()->strict_function_without_prototype_map(), |
1021 | "AsyncFunction" ); |
1022 | Map::SetPrototype(isolate(), map, async_function_prototype); |
1023 | native_context()->set_async_function_map(*map); |
1024 | |
1025 | map = Map::Copy(isolate(), isolate()->method_with_name_map(), |
1026 | "AsyncFunction with name" ); |
1027 | Map::SetPrototype(isolate(), map, async_function_prototype); |
1028 | native_context()->set_async_function_with_name_map(*map); |
1029 | |
1030 | map = Map::Copy(isolate(), isolate()->method_with_home_object_map(), |
1031 | "AsyncFunction with home object" ); |
1032 | Map::SetPrototype(isolate(), map, async_function_prototype); |
1033 | native_context()->set_async_function_with_home_object_map(*map); |
1034 | |
1035 | map = Map::Copy(isolate(), isolate()->method_with_name_and_home_object_map(), |
1036 | "AsyncFunction with name and home object" ); |
1037 | Map::SetPrototype(isolate(), map, async_function_prototype); |
1038 | native_context()->set_async_function_with_name_and_home_object_map(*map); |
1039 | } |
1040 | |
1041 | void Genesis::CreateJSProxyMaps() { |
1042 | // Allocate maps for all Proxy types. |
1043 | // Next to the default proxy, we need maps indicating callable and |
1044 | // constructable proxies. |
1045 | Handle<Map> proxy_map = factory()->NewMap(JS_PROXY_TYPE, JSProxy::kSize, |
1046 | TERMINAL_FAST_ELEMENTS_KIND); |
1047 | proxy_map->set_is_dictionary_map(true); |
1048 | proxy_map->set_may_have_interesting_symbols(true); |
1049 | native_context()->set_proxy_map(*proxy_map); |
1050 | |
1051 | Handle<Map> proxy_callable_map = |
1052 | Map::Copy(isolate_, proxy_map, "callable Proxy" ); |
1053 | proxy_callable_map->set_is_callable(true); |
1054 | native_context()->set_proxy_callable_map(*proxy_callable_map); |
1055 | proxy_callable_map->SetConstructor(native_context()->function_function()); |
1056 | |
1057 | Handle<Map> proxy_constructor_map = |
1058 | Map::Copy(isolate_, proxy_callable_map, "constructor Proxy" ); |
1059 | proxy_constructor_map->set_is_constructor(true); |
1060 | native_context()->set_proxy_constructor_map(*proxy_constructor_map); |
1061 | |
1062 | { |
1063 | Handle<Map> map = |
1064 | factory()->NewMap(JS_OBJECT_TYPE, JSProxyRevocableResult::kSize, |
1065 | TERMINAL_FAST_ELEMENTS_KIND, 2); |
1066 | Map::EnsureDescriptorSlack(isolate_, map, 2); |
1067 | |
1068 | { // proxy |
1069 | Descriptor d = Descriptor::DataField(isolate(), factory()->proxy_string(), |
1070 | JSProxyRevocableResult::kProxyIndex, |
1071 | NONE, Representation::Tagged()); |
1072 | map->AppendDescriptor(isolate(), &d); |
1073 | } |
1074 | { // revoke |
1075 | Descriptor d = Descriptor::DataField( |
1076 | isolate(), factory()->revoke_string(), |
1077 | JSProxyRevocableResult::kRevokeIndex, NONE, Representation::Tagged()); |
1078 | map->AppendDescriptor(isolate(), &d); |
1079 | } |
1080 | |
1081 | Map::SetPrototype(isolate(), map, isolate()->initial_object_prototype()); |
1082 | map->SetConstructor(native_context()->object_function()); |
1083 | |
1084 | native_context()->set_proxy_revocable_result_map(*map); |
1085 | } |
1086 | } |
1087 | |
1088 | namespace { |
1089 | void ReplaceAccessors(Isolate* isolate, Handle<Map> map, Handle<String> name, |
1090 | PropertyAttributes attributes, |
1091 | Handle<AccessorPair> accessor_pair) { |
1092 | DescriptorArray descriptors = map->instance_descriptors(); |
1093 | int idx = descriptors->SearchWithCache(isolate, *name, *map); |
1094 | Descriptor d = Descriptor::AccessorConstant(name, accessor_pair, attributes); |
1095 | descriptors->Replace(idx, &d); |
1096 | } |
1097 | } // namespace |
1098 | |
1099 | void Genesis::AddRestrictedFunctionProperties(Handle<JSFunction> empty) { |
1100 | PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM); |
1101 | Handle<JSFunction> thrower = GetThrowTypeErrorIntrinsic(); |
1102 | Handle<AccessorPair> accessors = factory()->NewAccessorPair(); |
1103 | accessors->set_getter(*thrower); |
1104 | accessors->set_setter(*thrower); |
1105 | |
1106 | Handle<Map> map(empty->map(), isolate()); |
1107 | ReplaceAccessors(isolate(), map, factory()->arguments_string(), rw_attribs, |
1108 | accessors); |
1109 | ReplaceAccessors(isolate(), map, factory()->caller_string(), rw_attribs, |
1110 | accessors); |
1111 | } |
1112 | |
1113 | static void AddToWeakNativeContextList(Isolate* isolate, Context context) { |
1114 | DCHECK(context->IsNativeContext()); |
1115 | Heap* heap = isolate->heap(); |
1116 | #ifdef DEBUG |
1117 | { // NOLINT |
1118 | DCHECK(context->next_context_link()->IsUndefined(isolate)); |
1119 | // Check that context is not in the list yet. |
1120 | for (Object current = heap->native_contexts_list(); |
1121 | !current->IsUndefined(isolate); |
1122 | current = Context::cast(current)->next_context_link()) { |
1123 | DCHECK(current != context); |
1124 | } |
1125 | } |
1126 | #endif |
1127 | context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list(), |
1128 | UPDATE_WEAK_WRITE_BARRIER); |
1129 | heap->set_native_contexts_list(context); |
1130 | } |
1131 | |
1132 | |
1133 | void Genesis::CreateRoots() { |
1134 | // Allocate the native context FixedArray first and then patch the |
1135 | // closure and extension object later (we need the empty function |
1136 | // and the global object, but in order to create those, we need the |
1137 | // native context). |
1138 | native_context_ = factory()->NewNativeContext(); |
1139 | AddToWeakNativeContextList(isolate(), *native_context()); |
1140 | isolate()->set_context(*native_context()); |
1141 | |
1142 | // Allocate the message listeners object. |
1143 | { |
1144 | Handle<TemplateList> list = TemplateList::New(isolate(), 1); |
1145 | native_context()->set_message_listeners(*list); |
1146 | } |
1147 | } |
1148 | |
1149 | |
1150 | void Genesis::InstallGlobalThisBinding() { |
1151 | Handle<ScriptContextTable> script_contexts( |
1152 | native_context()->script_context_table(), isolate()); |
1153 | Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate()); |
1154 | Handle<Context> context = |
1155 | factory()->NewScriptContext(native_context(), scope_info); |
1156 | |
1157 | // Go ahead and hook it up while we're at it. |
1158 | int slot = scope_info->ReceiverContextSlotIndex(); |
1159 | DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS); |
1160 | context->set(slot, native_context()->global_proxy()); |
1161 | |
1162 | Handle<ScriptContextTable> new_script_contexts = |
1163 | ScriptContextTable::Extend(script_contexts, context); |
1164 | native_context()->set_script_context_table(*new_script_contexts); |
1165 | } |
1166 | |
1167 | |
1168 | Handle<JSGlobalObject> Genesis::CreateNewGlobals( |
1169 | v8::Local<v8::ObjectTemplate> global_proxy_template, |
1170 | Handle<JSGlobalProxy> global_proxy) { |
1171 | // The argument global_proxy_template aka data is an ObjectTemplateInfo. |
1172 | // It has a constructor pointer that points at global_constructor which is a |
1173 | // FunctionTemplateInfo. |
1174 | // The global_proxy_constructor is used to (re)initialize the |
1175 | // global_proxy. The global_proxy_constructor also has a prototype_template |
1176 | // pointer that points at js_global_object_template which is an |
1177 | // ObjectTemplateInfo. |
1178 | // That in turn has a constructor pointer that points at |
1179 | // js_global_object_constructor which is a FunctionTemplateInfo. |
1180 | // js_global_object_constructor is used to make js_global_object_function |
1181 | // js_global_object_function is used to make the new global_object. |
1182 | // |
1183 | // --- G l o b a l --- |
1184 | // Step 1: Create a fresh JSGlobalObject. |
1185 | Handle<JSFunction> js_global_object_function; |
1186 | Handle<ObjectTemplateInfo> js_global_object_template; |
1187 | if (!global_proxy_template.IsEmpty()) { |
1188 | // Get prototype template of the global_proxy_template. |
1189 | Handle<ObjectTemplateInfo> data = |
1190 | v8::Utils::OpenHandle(*global_proxy_template); |
1191 | Handle<FunctionTemplateInfo> global_constructor = |
1192 | Handle<FunctionTemplateInfo>( |
1193 | FunctionTemplateInfo::cast(data->constructor()), isolate()); |
1194 | Handle<Object> proto_template(global_constructor->GetPrototypeTemplate(), |
1195 | isolate()); |
1196 | if (!proto_template->IsUndefined(isolate())) { |
1197 | js_global_object_template = |
1198 | Handle<ObjectTemplateInfo>::cast(proto_template); |
1199 | } |
1200 | } |
1201 | |
1202 | if (js_global_object_template.is_null()) { |
1203 | Handle<String> name = factory()->empty_string(); |
1204 | Handle<JSObject> prototype = |
1205 | factory()->NewFunctionPrototype(isolate()->object_function()); |
1206 | NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype( |
1207 | name, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize, 0, |
1208 | Builtins::kIllegal, MUTABLE); |
1209 | js_global_object_function = factory()->NewFunction(args); |
1210 | #ifdef DEBUG |
1211 | LookupIterator it(isolate(), prototype, factory()->constructor_string(), |
1212 | LookupIterator::OWN_SKIP_INTERCEPTOR); |
1213 | Handle<Object> value = Object::GetProperty(&it).ToHandleChecked(); |
1214 | DCHECK(it.IsFound()); |
1215 | DCHECK_EQ(*isolate()->object_function(), *value); |
1216 | #endif |
1217 | } else { |
1218 | Handle<FunctionTemplateInfo> js_global_object_constructor( |
1219 | FunctionTemplateInfo::cast(js_global_object_template->constructor()), |
1220 | isolate()); |
1221 | js_global_object_function = ApiNatives::CreateApiFunction( |
1222 | isolate(), js_global_object_constructor, factory()->the_hole_value(), |
1223 | JS_GLOBAL_OBJECT_TYPE); |
1224 | } |
1225 | |
1226 | js_global_object_function->initial_map()->set_is_prototype_map(true); |
1227 | js_global_object_function->initial_map()->set_is_dictionary_map(true); |
1228 | js_global_object_function->initial_map()->set_may_have_interesting_symbols( |
1229 | true); |
1230 | Handle<JSGlobalObject> global_object = |
1231 | factory()->NewJSGlobalObject(js_global_object_function); |
1232 | |
1233 | // Step 2: (re)initialize the global proxy object. |
1234 | Handle<JSFunction> global_proxy_function; |
1235 | if (global_proxy_template.IsEmpty()) { |
1236 | Handle<String> name = factory()->empty_string(); |
1237 | NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype( |
1238 | name, factory()->the_hole_value(), JS_GLOBAL_PROXY_TYPE, |
1239 | JSGlobalProxy::SizeWithEmbedderFields(0), 0, Builtins::kIllegal, |
1240 | MUTABLE); |
1241 | global_proxy_function = factory()->NewFunction(args); |
1242 | } else { |
1243 | Handle<ObjectTemplateInfo> data = |
1244 | v8::Utils::OpenHandle(*global_proxy_template); |
1245 | Handle<FunctionTemplateInfo> global_constructor( |
1246 | FunctionTemplateInfo::cast(data->constructor()), isolate()); |
1247 | global_proxy_function = ApiNatives::CreateApiFunction( |
1248 | isolate(), global_constructor, factory()->the_hole_value(), |
1249 | JS_GLOBAL_PROXY_TYPE); |
1250 | } |
1251 | global_proxy_function->initial_map()->set_is_access_check_needed(true); |
1252 | global_proxy_function->initial_map()->set_has_hidden_prototype(true); |
1253 | global_proxy_function->initial_map()->set_may_have_interesting_symbols(true); |
1254 | native_context()->set_global_proxy_function(*global_proxy_function); |
1255 | |
1256 | // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects |
1257 | // Return the global proxy. |
1258 | |
1259 | factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); |
1260 | |
1261 | // Set the native context for the global object. |
1262 | global_object->set_native_context(*native_context()); |
1263 | global_object->set_global_proxy(*global_proxy); |
1264 | // Set the native context of the global proxy. |
1265 | global_proxy->set_native_context(*native_context()); |
1266 | // Set the global proxy of the native context. If the native context has been |
1267 | // deserialized, the global proxy is already correctly set up by the |
1268 | // deserializer. Otherwise it's undefined. |
1269 | DCHECK(native_context() |
1270 | ->get(Context::GLOBAL_PROXY_INDEX) |
1271 | ->IsUndefined(isolate()) || |
1272 | native_context()->global_proxy() == *global_proxy); |
1273 | native_context()->set_global_proxy(*global_proxy); |
1274 | |
1275 | return global_object; |
1276 | } |
1277 | |
1278 | void Genesis::HookUpGlobalProxy(Handle<JSGlobalProxy> global_proxy) { |
1279 | // Re-initialize the global proxy with the global proxy function from the |
1280 | // snapshot, and then set up the link to the native context. |
1281 | Handle<JSFunction> global_proxy_function( |
1282 | native_context()->global_proxy_function(), isolate()); |
1283 | factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); |
1284 | Handle<JSObject> global_object( |
1285 | JSObject::cast(native_context()->global_object()), isolate()); |
1286 | JSObject::ForceSetPrototype(global_proxy, global_object); |
1287 | global_proxy->set_native_context(*native_context()); |
1288 | DCHECK(native_context()->global_proxy() == *global_proxy); |
1289 | } |
1290 | |
1291 | void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) { |
1292 | Handle<JSGlobalObject> global_object_from_snapshot( |
1293 | JSGlobalObject::cast(native_context()->extension()), isolate()); |
1294 | native_context()->set_extension(*global_object); |
1295 | native_context()->set_security_token(*global_object); |
1296 | |
1297 | TransferNamedProperties(global_object_from_snapshot, global_object); |
1298 | TransferIndexedProperties(global_object_from_snapshot, global_object); |
1299 | } |
1300 | |
1301 | static void InstallWithIntrinsicDefaultProto(Isolate* isolate, |
1302 | Handle<JSFunction> function, |
1303 | int context_index) { |
1304 | Handle<Smi> index(Smi::FromInt(context_index), isolate); |
1305 | JSObject::AddProperty(isolate, function, |
1306 | isolate->factory()->native_context_index_symbol(), |
1307 | index, NONE); |
1308 | isolate->native_context()->set(context_index, *function); |
1309 | } |
1310 | |
1311 | static void InstallError(Isolate* isolate, Handle<JSObject> global, |
1312 | Handle<String> name, int context_index) { |
1313 | Factory* factory = isolate->factory(); |
1314 | |
1315 | // Most Error objects consist of a message and a stack trace. |
1316 | // Reserve two in-object properties for these. |
1317 | const int kInObjectPropertiesCount = 2; |
1318 | const int kErrorObjectSize = |
1319 | JSObject::kHeaderSize + kInObjectPropertiesCount * kTaggedSize; |
1320 | Handle<JSFunction> error_fun = |
1321 | InstallFunction(isolate, global, name, JS_ERROR_TYPE, kErrorObjectSize, |
1322 | kInObjectPropertiesCount, factory->the_hole_value(), |
1323 | Builtins::kErrorConstructor); |
1324 | error_fun->shared()->DontAdaptArguments(); |
1325 | error_fun->shared()->set_length(1); |
1326 | |
1327 | if (context_index == Context::ERROR_FUNCTION_INDEX) { |
1328 | SimpleInstallFunction(isolate, error_fun, "captureStackTrace" , |
1329 | Builtins::kErrorCaptureStackTrace, 2, false); |
1330 | } |
1331 | |
1332 | InstallWithIntrinsicDefaultProto(isolate, error_fun, context_index); |
1333 | |
1334 | { |
1335 | // Setup %XXXErrorPrototype%. |
1336 | Handle<JSObject> prototype(JSObject::cast(error_fun->instance_prototype()), |
1337 | isolate); |
1338 | |
1339 | JSObject::AddProperty(isolate, prototype, factory->name_string(), name, |
1340 | DONT_ENUM); |
1341 | JSObject::AddProperty(isolate, prototype, factory->message_string(), |
1342 | factory->empty_string(), DONT_ENUM); |
1343 | |
1344 | if (context_index == Context::ERROR_FUNCTION_INDEX) { |
1345 | Handle<JSFunction> to_string_fun = |
1346 | SimpleInstallFunction(isolate, prototype, "toString" , |
1347 | Builtins::kErrorPrototypeToString, 0, true); |
1348 | isolate->native_context()->set_error_to_string(*to_string_fun); |
1349 | isolate->native_context()->set_initial_error_prototype(*prototype); |
1350 | } else { |
1351 | DCHECK(isolate->native_context()->error_to_string()->IsJSFunction()); |
1352 | |
1353 | JSObject::AddProperty(isolate, prototype, factory->toString_string(), |
1354 | isolate->error_to_string(), DONT_ENUM); |
1355 | |
1356 | Handle<JSFunction> global_error = isolate->error_function(); |
1357 | CHECK(JSReceiver::SetPrototype(error_fun, global_error, false, |
1358 | kThrowOnError) |
1359 | .FromMaybe(false)); |
1360 | CHECK(JSReceiver::SetPrototype(prototype, |
1361 | handle(global_error->prototype(), isolate), |
1362 | false, kThrowOnError) |
1363 | .FromMaybe(false)); |
1364 | } |
1365 | } |
1366 | |
1367 | Handle<Map> initial_map(error_fun->initial_map(), isolate); |
1368 | Map::EnsureDescriptorSlack(isolate, initial_map, 1); |
1369 | |
1370 | { |
1371 | Handle<AccessorInfo> info = factory->error_stack_accessor(); |
1372 | Descriptor d = Descriptor::AccessorConstant(handle(info->name(), isolate), |
1373 | info, DONT_ENUM); |
1374 | initial_map->AppendDescriptor(isolate, &d); |
1375 | } |
1376 | } |
1377 | |
1378 | namespace { |
1379 | |
1380 | void InstallMakeError(Isolate* isolate, int builtin_id, int context_index) { |
1381 | NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype( |
1382 | isolate->factory()->empty_string(), isolate->factory()->the_hole_value(), |
1383 | JS_OBJECT_TYPE, JSObject::kHeaderSize, 0, builtin_id, MUTABLE); |
1384 | |
1385 | Handle<JSFunction> function = isolate->factory()->NewFunction(args); |
1386 | function->shared()->DontAdaptArguments(); |
1387 | isolate->native_context()->set(context_index, *function); |
1388 | } |
1389 | |
1390 | } // namespace |
1391 | |
1392 | // This is only called if we are not using snapshots. The equivalent |
1393 | // work in the snapshot case is done in HookUpGlobalObject. |
1394 | void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, |
1395 | Handle<JSFunction> empty_function) { |
1396 | // --- N a t i v e C o n t e x t --- |
1397 | // Use the empty scope info. |
1398 | native_context()->set_scope_info(empty_function->shared()->scope_info()); |
1399 | native_context()->set_previous(Context()); |
1400 | // Set extension and global object. |
1401 | native_context()->set_extension(*global_object); |
1402 | // Security setup: Set the security token of the native context to the global |
1403 | // object. This makes the security check between two different contexts fail |
1404 | // by default even in case of global object reinitialization. |
1405 | native_context()->set_security_token(*global_object); |
1406 | |
1407 | Factory* factory = isolate_->factory(); |
1408 | |
1409 | Handle<ScriptContextTable> script_context_table = |
1410 | factory->NewScriptContextTable(); |
1411 | native_context()->set_script_context_table(*script_context_table); |
1412 | InstallGlobalThisBinding(); |
1413 | |
1414 | { // --- O b j e c t --- |
1415 | Handle<String> object_name = factory->Object_string(); |
1416 | Handle<JSFunction> object_function = isolate_->object_function(); |
1417 | JSObject::AddProperty(isolate_, global_object, object_name, object_function, |
1418 | DONT_ENUM); |
1419 | |
1420 | SimpleInstallFunction(isolate_, object_function, "assign" , |
1421 | Builtins::kObjectAssign, 2, false); |
1422 | SimpleInstallFunction(isolate_, object_function, "getOwnPropertyDescriptor" , |
1423 | Builtins::kObjectGetOwnPropertyDescriptor, 2, false); |
1424 | SimpleInstallFunction(isolate_, object_function, |
1425 | "getOwnPropertyDescriptors" , |
1426 | Builtins::kObjectGetOwnPropertyDescriptors, 1, false); |
1427 | SimpleInstallFunction(isolate_, object_function, "getOwnPropertyNames" , |
1428 | Builtins::kObjectGetOwnPropertyNames, 1, true); |
1429 | SimpleInstallFunction(isolate_, object_function, "getOwnPropertySymbols" , |
1430 | Builtins::kObjectGetOwnPropertySymbols, 1, false); |
1431 | SimpleInstallFunction(isolate_, object_function, "is" , Builtins::kObjectIs, |
1432 | 2, true); |
1433 | SimpleInstallFunction(isolate_, object_function, "preventExtensions" , |
1434 | Builtins::kObjectPreventExtensions, 1, false); |
1435 | SimpleInstallFunction(isolate_, object_function, "seal" , |
1436 | Builtins::kObjectSeal, 1, false); |
1437 | |
1438 | Handle<JSFunction> object_create = SimpleInstallFunction( |
1439 | isolate_, object_function, "create" , Builtins::kObjectCreate, 2, false); |
1440 | native_context()->set_object_create(*object_create); |
1441 | |
1442 | Handle<JSFunction> object_define_properties = |
1443 | SimpleInstallFunction(isolate_, object_function, "defineProperties" , |
1444 | Builtins::kObjectDefineProperties, 2, true); |
1445 | native_context()->set_object_define_properties(*object_define_properties); |
1446 | |
1447 | Handle<JSFunction> object_define_property = |
1448 | SimpleInstallFunction(isolate_, object_function, "defineProperty" , |
1449 | Builtins::kObjectDefineProperty, 3, true); |
1450 | native_context()->set_object_define_property(*object_define_property); |
1451 | |
1452 | SimpleInstallFunction(isolate_, object_function, "freeze" , |
1453 | Builtins::kObjectFreeze, 1, false); |
1454 | |
1455 | Handle<JSFunction> object_get_prototype_of = |
1456 | SimpleInstallFunction(isolate_, object_function, "getPrototypeOf" , |
1457 | Builtins::kObjectGetPrototypeOf, 1, false); |
1458 | native_context()->set_object_get_prototype_of(*object_get_prototype_of); |
1459 | SimpleInstallFunction(isolate_, object_function, "setPrototypeOf" , |
1460 | Builtins::kObjectSetPrototypeOf, 2, false); |
1461 | |
1462 | SimpleInstallFunction(isolate_, object_function, "isExtensible" , |
1463 | Builtins::kObjectIsExtensible, 1, false); |
1464 | SimpleInstallFunction(isolate_, object_function, "isFrozen" , |
1465 | Builtins::kObjectIsFrozen, 1, false); |
1466 | |
1467 | Handle<JSFunction> object_is_sealed = |
1468 | SimpleInstallFunction(isolate_, object_function, "isSealed" , |
1469 | Builtins::kObjectIsSealed, 1, false); |
1470 | native_context()->set_object_is_sealed(*object_is_sealed); |
1471 | |
1472 | Handle<JSFunction> object_keys = SimpleInstallFunction( |
1473 | isolate_, object_function, "keys" , Builtins::kObjectKeys, 1, true); |
1474 | native_context()->set_object_keys(*object_keys); |
1475 | SimpleInstallFunction(isolate_, object_function, "entries" , |
1476 | Builtins::kObjectEntries, 1, true); |
1477 | SimpleInstallFunction(isolate_, object_function, "values" , |
1478 | Builtins::kObjectValues, 1, true); |
1479 | |
1480 | SimpleInstallFunction(isolate_, isolate_->initial_object_prototype(), |
1481 | "__defineGetter__" , Builtins::kObjectDefineGetter, 2, |
1482 | true); |
1483 | SimpleInstallFunction(isolate_, isolate_->initial_object_prototype(), |
1484 | "__defineSetter__" , Builtins::kObjectDefineSetter, 2, |
1485 | true); |
1486 | SimpleInstallFunction(isolate_, isolate_->initial_object_prototype(), |
1487 | "hasOwnProperty" , |
1488 | Builtins::kObjectPrototypeHasOwnProperty, 1, true); |
1489 | SimpleInstallFunction(isolate_, isolate_->initial_object_prototype(), |
1490 | "__lookupGetter__" , Builtins::kObjectLookupGetter, 1, |
1491 | true); |
1492 | SimpleInstallFunction(isolate_, isolate_->initial_object_prototype(), |
1493 | "__lookupSetter__" , Builtins::kObjectLookupSetter, 1, |
1494 | true); |
1495 | SimpleInstallFunction(isolate_, isolate_->initial_object_prototype(), |
1496 | "isPrototypeOf" , |
1497 | Builtins::kObjectPrototypeIsPrototypeOf, 1, true); |
1498 | SimpleInstallFunction( |
1499 | isolate_, isolate_->initial_object_prototype(), "propertyIsEnumerable" , |
1500 | Builtins::kObjectPrototypePropertyIsEnumerable, 1, false); |
1501 | Handle<JSFunction> object_to_string = SimpleInstallFunction( |
1502 | isolate_, isolate_->initial_object_prototype(), "toString" , |
1503 | Builtins::kObjectPrototypeToString, 0, true); |
1504 | native_context()->set_object_to_string(*object_to_string); |
1505 | SimpleInstallFunction(isolate_, isolate_->initial_object_prototype(), |
1506 | "valueOf" , Builtins::kObjectPrototypeValueOf, 0, |
1507 | true); |
1508 | |
1509 | SimpleInstallGetterSetter( |
1510 | isolate_, isolate_->initial_object_prototype(), factory->proto_string(), |
1511 | Builtins::kObjectPrototypeGetProto, Builtins::kObjectPrototypeSetProto); |
1512 | |
1513 | SimpleInstallFunction(isolate_, isolate_->initial_object_prototype(), |
1514 | "toLocaleString" , |
1515 | Builtins::kObjectPrototypeToLocaleString, 0, true); |
1516 | } |
1517 | |
1518 | Handle<JSObject> global(native_context()->global_object(), isolate()); |
1519 | |
1520 | { // --- F u n c t i o n --- |
1521 | Handle<JSFunction> prototype = empty_function; |
1522 | Handle<JSFunction> function_fun = |
1523 | InstallFunction(isolate_, global, "Function" , JS_FUNCTION_TYPE, |
1524 | JSFunction::kSizeWithPrototype, 0, prototype, |
1525 | Builtins::kFunctionConstructor); |
1526 | // Function instances are sloppy by default. |
1527 | function_fun->set_prototype_or_initial_map( |
1528 | *isolate_->sloppy_function_map()); |
1529 | function_fun->shared()->DontAdaptArguments(); |
1530 | function_fun->shared()->set_length(1); |
1531 | InstallWithIntrinsicDefaultProto(isolate_, function_fun, |
1532 | Context::FUNCTION_FUNCTION_INDEX); |
1533 | |
1534 | // Setup the methods on the %FunctionPrototype%. |
1535 | JSObject::AddProperty(isolate_, prototype, factory->constructor_string(), |
1536 | function_fun, DONT_ENUM); |
1537 | SimpleInstallFunction(isolate_, prototype, "apply" , |
1538 | Builtins::kFunctionPrototypeApply, 2, false); |
1539 | SimpleInstallFunction(isolate_, prototype, "bind" , |
1540 | Builtins::kFastFunctionPrototypeBind, 1, false); |
1541 | SimpleInstallFunction(isolate_, prototype, "call" , |
1542 | Builtins::kFunctionPrototypeCall, 1, false); |
1543 | SimpleInstallFunction(isolate_, prototype, "toString" , |
1544 | Builtins::kFunctionPrototypeToString, 0, false); |
1545 | |
1546 | // Install the @@hasInstance function. |
1547 | Handle<JSFunction> has_instance = InstallFunctionAtSymbol( |
1548 | isolate_, prototype, factory->has_instance_symbol(), |
1549 | "[Symbol.hasInstance]" , Builtins::kFunctionPrototypeHasInstance, 1, |
1550 | true, |
1551 | static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY)); |
1552 | native_context()->set_function_has_instance(*has_instance); |
1553 | |
1554 | // Complete setting up function maps. |
1555 | { |
1556 | isolate_->sloppy_function_map()->SetConstructor(*function_fun); |
1557 | isolate_->sloppy_function_with_name_map()->SetConstructor(*function_fun); |
1558 | isolate_->sloppy_function_with_readonly_prototype_map()->SetConstructor( |
1559 | *function_fun); |
1560 | |
1561 | isolate_->strict_function_map()->SetConstructor(*function_fun); |
1562 | isolate_->strict_function_with_name_map()->SetConstructor(*function_fun); |
1563 | strict_function_with_home_object_map_->SetConstructor(*function_fun); |
1564 | strict_function_with_name_and_home_object_map_->SetConstructor( |
1565 | *function_fun); |
1566 | isolate_->strict_function_with_readonly_prototype_map()->SetConstructor( |
1567 | *function_fun); |
1568 | |
1569 | isolate_->class_function_map()->SetConstructor(*function_fun); |
1570 | } |
1571 | } |
1572 | |
1573 | { // --- A s y n c F r o m S y n c I t e r a t o r |
1574 | Handle<SharedFunctionInfo> info = SimpleCreateSharedFunctionInfo( |
1575 | isolate_, Builtins::kAsyncIteratorValueUnwrap, factory->empty_string(), |
1576 | 1); |
1577 | native_context()->set_async_iterator_value_unwrap_shared_fun(*info); |
1578 | } |
1579 | |
1580 | { // --- A s y n c G e n e r a t o r --- |
1581 | Handle<SharedFunctionInfo> info = SimpleCreateSharedFunctionInfo( |
1582 | isolate_, Builtins::kAsyncGeneratorAwaitResolveClosure, |
1583 | factory->empty_string(), 1); |
1584 | native_context()->set_async_generator_await_resolve_shared_fun(*info); |
1585 | |
1586 | info = SimpleCreateSharedFunctionInfo( |
1587 | isolate_, Builtins::kAsyncGeneratorAwaitRejectClosure, |
1588 | factory->empty_string(), 1); |
1589 | native_context()->set_async_generator_await_reject_shared_fun(*info); |
1590 | |
1591 | info = SimpleCreateSharedFunctionInfo( |
1592 | isolate_, Builtins::kAsyncGeneratorYieldResolveClosure, |
1593 | factory->empty_string(), 1); |
1594 | native_context()->set_async_generator_yield_resolve_shared_fun(*info); |
1595 | |
1596 | info = SimpleCreateSharedFunctionInfo( |
1597 | isolate_, Builtins::kAsyncGeneratorReturnResolveClosure, |
1598 | factory->empty_string(), 1); |
1599 | native_context()->set_async_generator_return_resolve_shared_fun(*info); |
1600 | |
1601 | info = SimpleCreateSharedFunctionInfo( |
1602 | isolate_, Builtins::kAsyncGeneratorReturnClosedResolveClosure, |
1603 | factory->empty_string(), 1); |
1604 | native_context()->set_async_generator_return_closed_resolve_shared_fun( |
1605 | *info); |
1606 | |
1607 | info = SimpleCreateSharedFunctionInfo( |
1608 | isolate_, Builtins::kAsyncGeneratorReturnClosedRejectClosure, |
1609 | factory->empty_string(), 1); |
1610 | native_context()->set_async_generator_return_closed_reject_shared_fun( |
1611 | *info); |
1612 | } |
1613 | |
1614 | Handle<JSFunction> array_prototype_to_string_fun; |
1615 | { // --- A r r a y --- |
1616 | Handle<JSFunction> array_function = InstallFunction( |
1617 | isolate_, global, "Array" , JS_ARRAY_TYPE, JSArray::kSize, 0, |
1618 | isolate_->initial_object_prototype(), Builtins::kArrayConstructor); |
1619 | array_function->shared()->DontAdaptArguments(); |
1620 | |
1621 | // This seems a bit hackish, but we need to make sure Array.length |
1622 | // is 1. |
1623 | array_function->shared()->set_length(1); |
1624 | |
1625 | Handle<Map> initial_map(array_function->initial_map(), isolate()); |
1626 | |
1627 | // This assert protects an optimization in |
1628 | // HGraphBuilder::JSArrayBuilder::EmitMapCode() |
1629 | DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind()); |
1630 | Map::EnsureDescriptorSlack(isolate_, initial_map, 1); |
1631 | |
1632 | PropertyAttributes attribs = static_cast<PropertyAttributes>( |
1633 | DONT_ENUM | DONT_DELETE); |
1634 | |
1635 | STATIC_ASSERT(JSArray::kLengthDescriptorIndex == 0); |
1636 | { // Add length. |
1637 | Descriptor d = Descriptor::AccessorConstant( |
1638 | factory->length_string(), factory->array_length_accessor(), attribs); |
1639 | initial_map->AppendDescriptor(isolate(), &d); |
1640 | } |
1641 | |
1642 | InstallWithIntrinsicDefaultProto(isolate_, array_function, |
1643 | Context::ARRAY_FUNCTION_INDEX); |
1644 | InstallSpeciesGetter(isolate_, array_function); |
1645 | |
1646 | // Cache the array maps, needed by ArrayConstructorStub |
1647 | CacheInitialJSArrayMaps(native_context(), initial_map); |
1648 | |
1649 | // Set up %ArrayPrototype%. |
1650 | // The %ArrayPrototype% has TERMINAL_FAST_ELEMENTS_KIND in order to ensure |
1651 | // that constant functions stay constant after turning prototype to setup |
1652 | // mode and back when constant field tracking is enabled. |
1653 | Handle<JSArray> proto = factory->NewJSArray(0, TERMINAL_FAST_ELEMENTS_KIND, |
1654 | AllocationType::kOld); |
1655 | JSFunction::SetPrototype(array_function, proto); |
1656 | native_context()->set_initial_array_prototype(*proto); |
1657 | |
1658 | Handle<JSFunction> is_arraylike = SimpleInstallFunction( |
1659 | isolate_, array_function, "isArray" , Builtins::kArrayIsArray, 1, true); |
1660 | native_context()->set_is_arraylike(*is_arraylike); |
1661 | |
1662 | SimpleInstallFunction(isolate_, array_function, "from" , |
1663 | Builtins::kArrayFrom, 1, false); |
1664 | SimpleInstallFunction(isolate_, array_function, "of" , Builtins::kArrayOf, 0, |
1665 | false); |
1666 | |
1667 | JSObject::AddProperty(isolate_, proto, factory->constructor_string(), |
1668 | array_function, DONT_ENUM); |
1669 | |
1670 | SimpleInstallFunction(isolate_, proto, "concat" , Builtins::kArrayConcat, 1, |
1671 | false); |
1672 | SimpleInstallFunction(isolate_, proto, "copyWithin" , |
1673 | Builtins::kArrayPrototypeCopyWithin, 2, false); |
1674 | SimpleInstallFunction(isolate_, proto, "fill" , |
1675 | Builtins::kArrayPrototypeFill, 1, false); |
1676 | SimpleInstallFunction(isolate_, proto, "find" , |
1677 | Builtins::kArrayPrototypeFind, 1, false); |
1678 | SimpleInstallFunction(isolate_, proto, "findIndex" , |
1679 | Builtins::kArrayPrototypeFindIndex, 1, false); |
1680 | SimpleInstallFunction(isolate_, proto, "lastIndexOf" , |
1681 | Builtins::kArrayPrototypeLastIndexOf, 1, false); |
1682 | SimpleInstallFunction(isolate_, proto, "pop" , Builtins::kArrayPrototypePop, |
1683 | 0, false); |
1684 | SimpleInstallFunction(isolate_, proto, "push" , |
1685 | Builtins::kArrayPrototypePush, 1, false); |
1686 | SimpleInstallFunction(isolate_, proto, "reverse" , |
1687 | Builtins::kArrayPrototypeReverse, 0, false); |
1688 | SimpleInstallFunction(isolate_, proto, "shift" , |
1689 | Builtins::kArrayPrototypeShift, 0, false); |
1690 | SimpleInstallFunction(isolate_, proto, "unshift" , |
1691 | Builtins::kArrayPrototypeUnshift, 1, false); |
1692 | SimpleInstallFunction(isolate_, proto, "slice" , |
1693 | Builtins::kArrayPrototypeSlice, 2, false); |
1694 | SimpleInstallFunction(isolate_, proto, "sort" , |
1695 | Builtins::kArrayPrototypeSort, 1, false); |
1696 | SimpleInstallFunction(isolate_, proto, "splice" , |
1697 | Builtins::kArrayPrototypeSplice, 2, false); |
1698 | SimpleInstallFunction(isolate_, proto, "includes" , Builtins::kArrayIncludes, |
1699 | 1, false); |
1700 | SimpleInstallFunction(isolate_, proto, "indexOf" , Builtins::kArrayIndexOf, |
1701 | 1, false); |
1702 | SimpleInstallFunction(isolate_, proto, "join" , |
1703 | Builtins::kArrayPrototypeJoin, 1, false); |
1704 | |
1705 | { // Set up iterator-related properties. |
1706 | Handle<JSFunction> keys = InstallFunctionWithBuiltinId( |
1707 | isolate_, proto, "keys" , Builtins::kArrayPrototypeKeys, 0, true); |
1708 | native_context()->set_array_keys_iterator(*keys); |
1709 | |
1710 | Handle<JSFunction> entries = InstallFunctionWithBuiltinId( |
1711 | isolate_, proto, "entries" , Builtins::kArrayPrototypeEntries, 0, |
1712 | true); |
1713 | native_context()->set_array_entries_iterator(*entries); |
1714 | |
1715 | Handle<JSFunction> values = InstallFunctionWithBuiltinId( |
1716 | isolate_, proto, "values" , Builtins::kArrayPrototypeValues, 0, true); |
1717 | JSObject::AddProperty(isolate_, proto, factory->iterator_symbol(), values, |
1718 | DONT_ENUM); |
1719 | native_context()->set_array_values_iterator(*values); |
1720 | } |
1721 | |
1722 | Handle<JSFunction> for_each_fun = SimpleInstallFunction( |
1723 | isolate_, proto, "forEach" , Builtins::kArrayForEach, 1, false); |
1724 | native_context()->set_array_for_each_iterator(*for_each_fun); |
1725 | SimpleInstallFunction(isolate_, proto, "filter" , Builtins::kArrayFilter, 1, |
1726 | false); |
1727 | SimpleInstallFunction(isolate_, proto, "flat" , |
1728 | Builtins::kArrayPrototypeFlat, 0, false); |
1729 | SimpleInstallFunction(isolate_, proto, "flatMap" , |
1730 | Builtins::kArrayPrototypeFlatMap, 1, false); |
1731 | SimpleInstallFunction(isolate_, proto, "map" , Builtins::kArrayMap, 1, |
1732 | false); |
1733 | SimpleInstallFunction(isolate_, proto, "every" , Builtins::kArrayEvery, 1, |
1734 | false); |
1735 | SimpleInstallFunction(isolate_, proto, "some" , Builtins::kArraySome, 1, |
1736 | false); |
1737 | SimpleInstallFunction(isolate_, proto, "reduce" , Builtins::kArrayReduce, 1, |
1738 | false); |
1739 | SimpleInstallFunction(isolate_, proto, "reduceRight" , |
1740 | Builtins::kArrayReduceRight, 1, false); |
1741 | SimpleInstallFunction(isolate_, proto, "toLocaleString" , |
1742 | Builtins::kArrayPrototypeToLocaleString, 0, false); |
1743 | array_prototype_to_string_fun = |
1744 | SimpleInstallFunction(isolate_, proto, "toString" , |
1745 | Builtins::kArrayPrototypeToString, 0, false); |
1746 | |
1747 | Handle<JSObject> unscopables = factory->NewJSObjectWithNullProto(); |
1748 | InstallTrueValuedProperty(isolate_, unscopables, "copyWithin" ); |
1749 | InstallTrueValuedProperty(isolate_, unscopables, "entries" ); |
1750 | InstallTrueValuedProperty(isolate_, unscopables, "fill" ); |
1751 | InstallTrueValuedProperty(isolate_, unscopables, "find" ); |
1752 | InstallTrueValuedProperty(isolate_, unscopables, "findIndex" ); |
1753 | InstallTrueValuedProperty(isolate_, unscopables, "flat" ); |
1754 | InstallTrueValuedProperty(isolate_, unscopables, "flatMap" ); |
1755 | InstallTrueValuedProperty(isolate_, unscopables, "includes" ); |
1756 | InstallTrueValuedProperty(isolate_, unscopables, "keys" ); |
1757 | InstallTrueValuedProperty(isolate_, unscopables, "values" ); |
1758 | JSObject::MigrateSlowToFast(unscopables, 0, "Bootstrapping" ); |
1759 | JSObject::AddProperty( |
1760 | isolate_, proto, factory->unscopables_symbol(), unscopables, |
1761 | static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); |
1762 | |
1763 | Handle<Map> map(proto->map(), isolate_); |
1764 | Map::SetShouldBeFastPrototypeMap(map, true, isolate_); |
1765 | } |
1766 | |
1767 | { // --- A r r a y I t e r a t o r --- |
1768 | Handle<JSObject> iterator_prototype( |
1769 | native_context()->initial_iterator_prototype(), isolate()); |
1770 | |
1771 | Handle<JSObject> array_iterator_prototype = |
1772 | factory->NewJSObject(isolate_->object_function(), AllocationType::kOld); |
1773 | JSObject::ForceSetPrototype(array_iterator_prototype, iterator_prototype); |
1774 | |
1775 | InstallToStringTag(isolate_, array_iterator_prototype, |
1776 | factory->ArrayIterator_string()); |
1777 | |
1778 | InstallFunctionWithBuiltinId(isolate_, array_iterator_prototype, "next" , |
1779 | Builtins::kArrayIteratorPrototypeNext, 0, |
1780 | true); |
1781 | |
1782 | Handle<JSFunction> array_iterator_function = |
1783 | CreateFunction(isolate_, factory->ArrayIterator_string(), |
1784 | JS_ARRAY_ITERATOR_TYPE, JSArrayIterator::kSize, 0, |
1785 | array_iterator_prototype, Builtins::kIllegal); |
1786 | array_iterator_function->shared()->set_native(false); |
1787 | |
1788 | native_context()->set_initial_array_iterator_map( |
1789 | array_iterator_function->initial_map()); |
1790 | native_context()->set_initial_array_iterator_prototype( |
1791 | *array_iterator_prototype); |
1792 | } |
1793 | |
1794 | { // --- N u m b e r --- |
1795 | Handle<JSFunction> number_fun = InstallFunction( |
1796 | isolate_, global, "Number" , JS_VALUE_TYPE, JSValue::kSize, 0, |
1797 | isolate_->initial_object_prototype(), Builtins::kNumberConstructor); |
1798 | number_fun->shared()->DontAdaptArguments(); |
1799 | number_fun->shared()->set_length(1); |
1800 | InstallWithIntrinsicDefaultProto(isolate_, number_fun, |
1801 | Context::NUMBER_FUNCTION_INDEX); |
1802 | |
1803 | // Create the %NumberPrototype% |
1804 | Handle<JSValue> prototype = Handle<JSValue>::cast( |
1805 | factory->NewJSObject(number_fun, AllocationType::kOld)); |
1806 | prototype->set_value(Smi::kZero); |
1807 | JSFunction::SetPrototype(number_fun, prototype); |
1808 | |
1809 | // Install the "constructor" property on the {prototype}. |
1810 | JSObject::AddProperty(isolate_, prototype, factory->constructor_string(), |
1811 | number_fun, DONT_ENUM); |
1812 | |
1813 | // Install the Number.prototype methods. |
1814 | SimpleInstallFunction(isolate_, prototype, "toExponential" , |
1815 | Builtins::kNumberPrototypeToExponential, 1, false); |
1816 | SimpleInstallFunction(isolate_, prototype, "toFixed" , |
1817 | Builtins::kNumberPrototypeToFixed, 1, false); |
1818 | SimpleInstallFunction(isolate_, prototype, "toPrecision" , |
1819 | Builtins::kNumberPrototypeToPrecision, 1, false); |
1820 | SimpleInstallFunction(isolate_, prototype, "toString" , |
1821 | Builtins::kNumberPrototypeToString, 1, false); |
1822 | SimpleInstallFunction(isolate_, prototype, "valueOf" , |
1823 | Builtins::kNumberPrototypeValueOf, 0, true); |
1824 | |
1825 | SimpleInstallFunction(isolate_, prototype, "toLocaleString" , |
1826 | Builtins::kNumberPrototypeToLocaleString, 0, false); |
1827 | |
1828 | // Install the Number functions. |
1829 | SimpleInstallFunction(isolate_, number_fun, "isFinite" , |
1830 | Builtins::kNumberIsFinite, 1, true); |
1831 | SimpleInstallFunction(isolate_, number_fun, "isInteger" , |
1832 | Builtins::kNumberIsInteger, 1, true); |
1833 | SimpleInstallFunction(isolate_, number_fun, "isNaN" , Builtins::kNumberIsNaN, |
1834 | 1, true); |
1835 | SimpleInstallFunction(isolate_, number_fun, "isSafeInteger" , |
1836 | Builtins::kNumberIsSafeInteger, 1, true); |
1837 | |
1838 | // Install Number.parseFloat and Global.parseFloat. |
1839 | Handle<JSFunction> parse_float_fun = |
1840 | SimpleInstallFunction(isolate_, number_fun, "parseFloat" , |
1841 | Builtins::kNumberParseFloat, 1, true); |
1842 | JSObject::AddProperty(isolate_, global_object, "parseFloat" , |
1843 | parse_float_fun, DONT_ENUM); |
1844 | |
1845 | // Install Number.parseInt and Global.parseInt. |
1846 | Handle<JSFunction> parse_int_fun = SimpleInstallFunction( |
1847 | isolate_, number_fun, "parseInt" , Builtins::kNumberParseInt, 2, true); |
1848 | JSObject::AddProperty(isolate_, global_object, "parseInt" , parse_int_fun, |
1849 | DONT_ENUM); |
1850 | |
1851 | // Install Number constants |
1852 | const double kMaxValue = 1.7976931348623157e+308; |
1853 | const double kMinValue = 5e-324; |
1854 | const double kMinSafeInteger = -kMaxSafeInteger; |
1855 | const double kEPS = 2.220446049250313e-16; |
1856 | |
1857 | InstallConstant(isolate_, number_fun, "MAX_VALUE" , |
1858 | factory->NewNumber(kMaxValue)); |
1859 | InstallConstant(isolate_, number_fun, "MIN_VALUE" , |
1860 | factory->NewNumber(kMinValue)); |
1861 | InstallConstant(isolate_, number_fun, "NaN" , factory->nan_value()); |
1862 | InstallConstant(isolate_, number_fun, "NEGATIVE_INFINITY" , |
1863 | factory->NewNumber(-V8_INFINITY)); |
1864 | InstallConstant(isolate_, number_fun, "POSITIVE_INFINITY" , |
1865 | factory->infinity_value()); |
1866 | InstallConstant(isolate_, number_fun, "MAX_SAFE_INTEGER" , |
1867 | factory->NewNumber(kMaxSafeInteger)); |
1868 | InstallConstant(isolate_, number_fun, "MIN_SAFE_INTEGER" , |
1869 | factory->NewNumber(kMinSafeInteger)); |
1870 | InstallConstant(isolate_, number_fun, "EPSILON" , factory->NewNumber(kEPS)); |
1871 | |
1872 | InstallConstant(isolate_, global, "Infinity" , |
---|