blob: cedb0efd00127bf54461832b2b706de4db675d0c [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "accessors.h"
31#include "api.h"
32#include "bootstrapper.h"
33#include "compiler.h"
34#include "debug.h"
35#include "execution.h"
36#include "global-handles.h"
Ben Murdoch592a9fc2012-03-05 11:04:45 +000037#include "isolate-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000038#include "macro-assembler.h"
39#include "natives.h"
Iain Merrick75681382010-08-19 15:07:18 +010040#include "objects-visiting.h"
Ben Murdoch592a9fc2012-03-05 11:04:45 +000041#include "platform.h"
Steve Blockd0582a62009-12-15 09:54:21 +000042#include "snapshot.h"
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080043#include "extensions/externalize-string-extension.h"
44#include "extensions/gc-extension.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000045
46namespace v8 {
47namespace internal {
48
Steve Blocka7e24c12009-10-30 11:49:00 +000049
Steve Block44f0eee2011-05-26 01:26:41 +010050NativesExternalStringResource::NativesExternalStringResource(
51 Bootstrapper* bootstrapper,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000052 const char* source,
53 size_t length)
54 : data_(source), length_(length) {
Steve Block44f0eee2011-05-26 01:26:41 +010055 if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
56 bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
Steve Blockd0582a62009-12-15 09:54:21 +000057 }
58 // The resources are small objects and we only make a fixed number of
59 // them, but let's clean them up on exit for neatness.
Steve Block44f0eee2011-05-26 01:26:41 +010060 bootstrapper->delete_these_non_arrays_on_tear_down_->
Steve Blockd0582a62009-12-15 09:54:21 +000061 Add(reinterpret_cast<char*>(this));
62}
Steve Blocka7e24c12009-10-30 11:49:00 +000063
64
Steve Block44f0eee2011-05-26 01:26:41 +010065Bootstrapper::Bootstrapper()
66 : nesting_(0),
67 extensions_cache_(Script::TYPE_EXTENSION),
68 delete_these_non_arrays_on_tear_down_(NULL),
69 delete_these_arrays_on_tear_down_(NULL) {
70}
71
72
Steve Blocka7e24c12009-10-30 11:49:00 +000073Handle<String> Bootstrapper::NativesSourceLookup(int index) {
74 ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
Steve Block44f0eee2011-05-26 01:26:41 +010075 Isolate* isolate = Isolate::Current();
76 Factory* factory = isolate->factory();
77 Heap* heap = isolate->heap();
78 if (heap->natives_source_cache()->get(index)->IsUndefined()) {
Steve Blockd0582a62009-12-15 09:54:21 +000079 if (!Snapshot::IsEnabled() || FLAG_new_snapshot) {
80 // We can use external strings for the natives.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000081 Vector<const char> source = Natives::GetRawScriptSource(index);
Steve Blockd0582a62009-12-15 09:54:21 +000082 NativesExternalStringResource* resource =
Steve Block44f0eee2011-05-26 01:26:41 +010083 new NativesExternalStringResource(this,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000084 source.start(),
85 source.length());
Steve Blockd0582a62009-12-15 09:54:21 +000086 Handle<String> source_code =
Steve Block44f0eee2011-05-26 01:26:41 +010087 factory->NewExternalStringFromAscii(resource);
88 heap->natives_source_cache()->set(index, *source_code);
Steve Blockd0582a62009-12-15 09:54:21 +000089 } else {
90 // Old snapshot code can't cope with external strings at all.
91 Handle<String> source_code =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000092 factory->NewStringFromAscii(Natives::GetRawScriptSource(index));
Steve Block44f0eee2011-05-26 01:26:41 +010093 heap->natives_source_cache()->set(index, *source_code);
Steve Blockd0582a62009-12-15 09:54:21 +000094 }
Steve Blocka7e24c12009-10-30 11:49:00 +000095 }
Steve Block44f0eee2011-05-26 01:26:41 +010096 Handle<Object> cached_source(heap->natives_source_cache()->get(index));
Steve Blocka7e24c12009-10-30 11:49:00 +000097 return Handle<String>::cast(cached_source);
98}
99
100
Steve Blocka7e24c12009-10-30 11:49:00 +0000101void Bootstrapper::Initialize(bool create_heap_objects) {
Steve Block44f0eee2011-05-26 01:26:41 +0100102 extensions_cache_.Initialize(create_heap_objects);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800103 GCExtension::Register();
104 ExternalizeStringExtension::Register();
Steve Blocka7e24c12009-10-30 11:49:00 +0000105}
106
107
Leon Clarkee46be812010-01-19 14:06:41 +0000108char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
109 char* memory = new char[bytes];
110 if (memory != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +0100111 if (delete_these_arrays_on_tear_down_ == NULL) {
112 delete_these_arrays_on_tear_down_ = new List<char*>(2);
Leon Clarkee46be812010-01-19 14:06:41 +0000113 }
Steve Block44f0eee2011-05-26 01:26:41 +0100114 delete_these_arrays_on_tear_down_->Add(memory);
Leon Clarkee46be812010-01-19 14:06:41 +0000115 }
116 return memory;
117}
118
119
Steve Blocka7e24c12009-10-30 11:49:00 +0000120void Bootstrapper::TearDown() {
Steve Block44f0eee2011-05-26 01:26:41 +0100121 if (delete_these_non_arrays_on_tear_down_ != NULL) {
122 int len = delete_these_non_arrays_on_tear_down_->length();
Steve Blockd0582a62009-12-15 09:54:21 +0000123 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
124 for (int i = 0; i < len; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100125 delete delete_these_non_arrays_on_tear_down_->at(i);
126 delete_these_non_arrays_on_tear_down_->at(i) = NULL;
Steve Blockd0582a62009-12-15 09:54:21 +0000127 }
Steve Block44f0eee2011-05-26 01:26:41 +0100128 delete delete_these_non_arrays_on_tear_down_;
129 delete_these_non_arrays_on_tear_down_ = NULL;
Steve Blockd0582a62009-12-15 09:54:21 +0000130 }
131
Steve Block44f0eee2011-05-26 01:26:41 +0100132 if (delete_these_arrays_on_tear_down_ != NULL) {
133 int len = delete_these_arrays_on_tear_down_->length();
Leon Clarkee46be812010-01-19 14:06:41 +0000134 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations.
135 for (int i = 0; i < len; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100136 delete[] delete_these_arrays_on_tear_down_->at(i);
137 delete_these_arrays_on_tear_down_->at(i) = NULL;
Leon Clarkee46be812010-01-19 14:06:41 +0000138 }
Steve Block44f0eee2011-05-26 01:26:41 +0100139 delete delete_these_arrays_on_tear_down_;
140 delete_these_arrays_on_tear_down_ = NULL;
Leon Clarkee46be812010-01-19 14:06:41 +0000141 }
142
Steve Block44f0eee2011-05-26 01:26:41 +0100143 extensions_cache_.Initialize(false); // Yes, symmetrical
Steve Blocka7e24c12009-10-30 11:49:00 +0000144}
145
146
Steve Blocka7e24c12009-10-30 11:49:00 +0000147class Genesis BASE_EMBEDDED {
148 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000149 Genesis(Isolate* isolate,
150 Handle<Object> global_object,
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 v8::Handle<v8::ObjectTemplate> global_template,
152 v8::ExtensionConfiguration* extensions);
Andrei Popescu31002712010-02-23 13:46:05 +0000153 ~Genesis() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000154
155 Handle<Context> result() { return result_; }
156
157 Genesis* previous() { return previous_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000158
Ben Murdoch257744e2011-11-30 15:57:28 +0000159 Isolate* isolate() const { return isolate_; }
160 Factory* factory() const { return isolate_->factory(); }
161 Heap* heap() const { return isolate_->heap(); }
162
Steve Blocka7e24c12009-10-30 11:49:00 +0000163 private:
164 Handle<Context> global_context_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000165 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000166
167 // There may be more than one active genesis object: When GC is
168 // triggered during environment creation there may be weak handle
169 // processing callbacks which may create new environments.
170 Genesis* previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000171
172 Handle<Context> global_context() { return global_context_; }
173
Andrei Popescu31002712010-02-23 13:46:05 +0000174 // Creates some basic objects. Used for creating a context from scratch.
175 void CreateRoots();
176 // Creates the empty function. Used for creating a context from scratch.
Ben Murdoch257744e2011-11-30 15:57:28 +0000177 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
Steve Block44f0eee2011-05-26 01:26:41 +0100178 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
Ben Murdoch257744e2011-11-30 15:57:28 +0000179 Handle<JSFunction> GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +0100180
181 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
Andrei Popescu31002712010-02-23 13:46:05 +0000182 // Creates the global objects using the global and the template passed in
183 // 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 used the deserialized ones that are linked together with the
187 // rest of the context snapshot.
188 Handle<JSGlobalProxy> CreateNewGlobals(
189 v8::Handle<v8::ObjectTemplate> global_template,
190 Handle<Object> global_object,
191 Handle<GlobalObject>* global_proxy_out);
192 // Hooks the given global proxy into the context. If the context was created
193 // by deserialization then this will unhook the global proxy that was
194 // deserialized, leaving the GC to pick it up.
195 void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
196 Handle<JSGlobalProxy> global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +0000197 // Similarly, we want to use the inner global that has been created by the
198 // templates passed through the API. The inner global from the snapshot is
199 // detached from the other objects in the snapshot.
200 void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
Andrei Popescu31002712010-02-23 13:46:05 +0000201 // New context initialization. Used for creating a context from scratch.
202 void InitializeGlobal(Handle<GlobalObject> inner_global,
203 Handle<JSFunction> empty_function);
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000204 void InitializeExperimentalGlobal();
Andrei Popescu31002712010-02-23 13:46:05 +0000205 // Installs the contents of the native .js files on the global objects.
206 // Used for creating a context from scratch.
Steve Blocka7e24c12009-10-30 11:49:00 +0000207 void InstallNativeFunctions();
Ben Murdoch257744e2011-11-30 15:57:28 +0000208 void InstallExperimentalNativeFunctions();
Steve Blocka7e24c12009-10-30 11:49:00 +0000209 bool InstallNatives();
Ben Murdoch257744e2011-11-30 15:57:28 +0000210 bool InstallExperimentalNatives();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100211 void InstallBuiltinFunctionIds();
Steve Block6ded16b2010-05-10 14:33:55 +0100212 void InstallJSFunctionResultCaches();
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100213 void InitializeNormalizedMapCaches();
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000214
215 enum ExtensionTraversalState {
216 UNVISITED, VISITED, INSTALLED
217 };
218
219 class ExtensionStates {
220 public:
221 ExtensionStates();
222 ExtensionTraversalState get_state(RegisteredExtension* extension);
223 void set_state(RegisteredExtension* extension,
224 ExtensionTraversalState state);
225 private:
226 Allocator allocator_;
227 HashMap map_;
228 DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
229 };
230
Andrei Popescu31002712010-02-23 13:46:05 +0000231 // Used both for deserialized and from-scratch contexts to add the extensions
232 // provided.
233 static bool InstallExtensions(Handle<Context> global_context,
234 v8::ExtensionConfiguration* extensions);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000235 static bool InstallExtension(const char* name,
236 ExtensionStates* extension_states);
237 static bool InstallExtension(v8::RegisteredExtension* current,
238 ExtensionStates* extension_states);
Andrei Popescu31002712010-02-23 13:46:05 +0000239 static void InstallSpecialObjects(Handle<Context> global_context);
Andrei Popescu402d9372010-02-26 13:31:12 +0000240 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
Steve Blocka7e24c12009-10-30 11:49:00 +0000241 bool ConfigureApiObject(Handle<JSObject> object,
242 Handle<ObjectTemplateInfo> object_template);
243 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
244
245 // Migrates all properties from the 'from' object to the 'to'
246 // object and overrides the prototype in 'to' with the one from
247 // 'from'.
248 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
249 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
250 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
251
Steve Block6ded16b2010-05-10 14:33:55 +0100252 enum PrototypePropertyMode {
253 DONT_ADD_PROTOTYPE,
254 ADD_READONLY_PROTOTYPE,
255 ADD_WRITEABLE_PROTOTYPE
256 };
Steve Block44f0eee2011-05-26 01:26:41 +0100257
258 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
259
Steve Blocka7e24c12009-10-30 11:49:00 +0000260 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
Steve Block6ded16b2010-05-10 14:33:55 +0100261 PrototypePropertyMode prototypeMode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000262 void MakeFunctionInstancePrototypeWritable();
263
Steve Block44f0eee2011-05-26 01:26:41 +0100264 Handle<Map> CreateStrictModeFunctionMap(
265 PrototypePropertyMode prototype_mode,
266 Handle<JSFunction> empty_function,
Ben Murdochc7cc0282012-03-05 14:35:55 +0000267 Handle<AccessorPair> arguments_callbacks,
268 Handle<AccessorPair> caller_callbacks);
Steve Block44f0eee2011-05-26 01:26:41 +0100269
270 Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
271 PrototypePropertyMode propertyMode,
Ben Murdochc7cc0282012-03-05 14:35:55 +0000272 Handle<AccessorPair> arguments,
273 Handle<AccessorPair> caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100274
Ben Murdoch257744e2011-11-30 15:57:28 +0000275 static bool CompileBuiltin(Isolate* isolate, int index);
276 static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000277 static bool CompileNative(Vector<const char> name, Handle<String> source);
278 static bool CompileScriptCached(Vector<const char> name,
279 Handle<String> source,
280 SourceCodeCache* cache,
281 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +0000282 Handle<Context> top_context,
Steve Blocka7e24c12009-10-30 11:49:00 +0000283 bool use_runtime_context);
284
285 Handle<Context> result_;
Steve Block44f0eee2011-05-26 01:26:41 +0100286
287 // Function instance maps. Function literal maps are created initially with
288 // a read only prototype for the processing of JS builtins. Later the function
289 // instance maps are replaced in order to make prototype writable.
290 // These are the final, writable prototype, maps.
291 Handle<Map> function_instance_map_writable_prototype_;
292 Handle<Map> strict_mode_function_instance_map_writable_prototype_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000293 Handle<JSFunction> throw_type_error_function;
Steve Block44f0eee2011-05-26 01:26:41 +0100294
Andrei Popescu31002712010-02-23 13:46:05 +0000295 BootstrapperActive active_;
296 friend class Bootstrapper;
Steve Blocka7e24c12009-10-30 11:49:00 +0000297};
298
Steve Blocka7e24c12009-10-30 11:49:00 +0000299
300void Bootstrapper::Iterate(ObjectVisitor* v) {
Steve Block44f0eee2011-05-26 01:26:41 +0100301 extensions_cache_.Iterate(v);
Ben Murdochc7cc0282012-03-05 14:35:55 +0000302 v->Synchronize(VisitorSynchronization::kExtensions);
Steve Blocka7e24c12009-10-30 11:49:00 +0000303}
304
305
Steve Blocka7e24c12009-10-30 11:49:00 +0000306Handle<Context> Bootstrapper::CreateEnvironment(
Ben Murdoch257744e2011-11-30 15:57:28 +0000307 Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +0000308 Handle<Object> global_object,
309 v8::Handle<v8::ObjectTemplate> global_template,
310 v8::ExtensionConfiguration* extensions) {
Andrei Popescu31002712010-02-23 13:46:05 +0000311 HandleScope scope;
312 Handle<Context> env;
Ben Murdoch257744e2011-11-30 15:57:28 +0000313 Genesis genesis(isolate, global_object, global_template, extensions);
Andrei Popescu31002712010-02-23 13:46:05 +0000314 env = genesis.result();
315 if (!env.is_null()) {
316 if (InstallExtensions(env, extensions)) {
317 return env;
318 }
319 }
320 return Handle<Context>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000321}
322
323
324static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
325 // object.__proto__ = proto;
Ben Murdoch257744e2011-11-30 15:57:28 +0000326 Factory* factory = object->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +0000327 Handle<Map> old_to_map = Handle<Map>(object->map());
Ben Murdoch257744e2011-11-30 15:57:28 +0000328 Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000329 new_to_map->set_prototype(*proto);
330 object->set_map(*new_to_map);
331}
332
333
334void Bootstrapper::DetachGlobal(Handle<Context> env) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000335 Factory* factory = env->GetIsolate()->factory();
Steve Block44f0eee2011-05-26 01:26:41 +0100336 JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000337 SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
Steve Block44f0eee2011-05-26 01:26:41 +0100338 factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000339 env->set_global_proxy(env->global());
340 env->global()->set_global_receiver(env->global());
341}
342
343
Andrei Popescu74b3c142010-03-29 12:03:09 +0100344void Bootstrapper::ReattachGlobal(Handle<Context> env,
345 Handle<Object> global_object) {
346 ASSERT(global_object->IsJSGlobalProxy());
347 Handle<JSGlobalProxy> global = Handle<JSGlobalProxy>::cast(global_object);
348 env->global()->set_global_receiver(*global);
349 env->set_global_proxy(*global);
350 SetObjectPrototype(global, Handle<JSObject>(env->global()));
351 global->set_context(*env);
352}
353
354
Steve Blocka7e24c12009-10-30 11:49:00 +0000355static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
356 const char* name,
357 InstanceType type,
358 int instance_size,
359 Handle<JSObject> prototype,
360 Builtins::Name call,
361 bool is_ecma_native) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000362 Isolate* isolate = target->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100363 Factory* factory = isolate->factory();
364 Handle<String> symbol = factory->LookupAsciiSymbol(name);
365 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
Steve Block6ded16b2010-05-10 14:33:55 +0100366 Handle<JSFunction> function = prototype.is_null() ?
Steve Block44f0eee2011-05-26 01:26:41 +0100367 factory->NewFunctionWithoutPrototype(symbol, call_code) :
368 factory->NewFunctionWithPrototype(symbol,
Steve Blocka7e24c12009-10-30 11:49:00 +0000369 type,
370 instance_size,
371 prototype,
372 call_code,
373 is_ecma_native);
Ben Murdoch589d6972011-11-30 16:04:58 +0000374 PropertyAttributes attributes;
375 if (target->IsJSBuiltinsObject()) {
376 attributes =
377 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
378 } else {
379 attributes = DONT_ENUM;
380 }
Ben Murdochc7cc0282012-03-05 14:35:55 +0000381 CHECK_NOT_EMPTY_HANDLE(isolate,
382 JSObject::SetLocalPropertyIgnoreAttributes(
383 target, symbol, function, attributes));
Steve Blocka7e24c12009-10-30 11:49:00 +0000384 if (is_ecma_native) {
385 function->shared()->set_instance_class_name(*symbol);
386 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000387 function->shared()->set_native(true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000388 return function;
389}
390
391
392Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
Steve Block6ded16b2010-05-10 14:33:55 +0100393 PrototypePropertyMode prototypeMode) {
Steve Block44f0eee2011-05-26 01:26:41 +0100394 Handle<DescriptorArray> descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000395 factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
396 ? 4
397 : 5);
Steve Block6ded16b2010-05-10 14:33:55 +0100398 PropertyAttributes attributes =
Steve Blocka7e24c12009-10-30 11:49:00 +0000399 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Steve Blocka7e24c12009-10-30 11:49:00 +0000400
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000401 DescriptorArray::WhitenessWitness witness(*descriptors);
402
Steve Block44f0eee2011-05-26 01:26:41 +0100403 { // Add length.
Ben Murdoch257744e2011-11-30 15:57:28 +0000404 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
405 CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000406 descriptors->Set(0, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100407 }
408 { // Add name.
Ben Murdoch257744e2011-11-30 15:57:28 +0000409 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
410 CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000411 descriptors->Set(1, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100412 }
413 { // Add arguments.
Ben Murdoch257744e2011-11-30 15:57:28 +0000414 Handle<Foreign> foreign =
415 factory()->NewForeign(&Accessors::FunctionArguments);
416 CallbacksDescriptor d(*factory()->arguments_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000417 descriptors->Set(2, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100418 }
419 { // Add caller.
Ben Murdoch257744e2011-11-30 15:57:28 +0000420 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionCaller);
421 CallbacksDescriptor d(*factory()->caller_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000422 descriptors->Set(3, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100423 }
424 if (prototypeMode != DONT_ADD_PROTOTYPE) {
425 // Add prototype.
426 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
427 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
428 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000429 Handle<Foreign> foreign =
430 factory()->NewForeign(&Accessors::FunctionPrototype);
431 CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000432 descriptors->Set(4, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100433 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000434 descriptors->Sort(witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100435 return descriptors;
436}
Steve Blocka7e24c12009-10-30 11:49:00 +0000437
Steve Blocka7e24c12009-10-30 11:49:00 +0000438
Steve Block44f0eee2011-05-26 01:26:41 +0100439Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000440 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Steve Block44f0eee2011-05-26 01:26:41 +0100441 Handle<DescriptorArray> descriptors =
442 ComputeFunctionInstanceDescriptor(prototype_mode);
443 map->set_instance_descriptors(*descriptors);
444 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
445 return map;
Steve Blocka7e24c12009-10-30 11:49:00 +0000446}
447
448
Ben Murdoch257744e2011-11-30 15:57:28 +0000449Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100450 // Allocate the map for function instances. Maps are allocated first and their
451 // prototypes patched later, once empty function is created.
452
Steve Blocka7e24c12009-10-30 11:49:00 +0000453 // Please note that the prototype property for function instances must be
454 // writable.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100455 Handle<Map> function_instance_map =
456 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
457 global_context()->set_function_instance_map(*function_instance_map);
Steve Block6ded16b2010-05-10 14:33:55 +0100458
459 // Functions with this map will not have a 'prototype' property, and
460 // can not be used as constructors.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100461 Handle<Map> function_without_prototype_map =
462 CreateFunctionMap(DONT_ADD_PROTOTYPE);
Steve Block6ded16b2010-05-10 14:33:55 +0100463 global_context()->set_function_without_prototype_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100464 *function_without_prototype_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000465
Steve Block44f0eee2011-05-26 01:26:41 +0100466 // Allocate the function map. This map is temporary, used only for processing
467 // of builtins.
468 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100469 Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
470 global_context()->set_function_map(*function_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000471
Steve Block44f0eee2011-05-26 01:26:41 +0100472 // The final map for functions. Writeable prototype.
473 // This map is installed in MakeFunctionInstancePrototypeWritable.
474 function_instance_map_writable_prototype_ =
475 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
476
Steve Block44f0eee2011-05-26 01:26:41 +0100477 Factory* factory = isolate->factory();
478 Heap* heap = isolate->heap();
479
480 Handle<String> object_name = Handle<String>(heap->Object_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +0000481
482 { // --- O b j e c t ---
483 Handle<JSFunction> object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +0100484 factory->NewFunction(object_name, factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000485 Handle<Map> object_function_map =
Steve Block44f0eee2011-05-26 01:26:41 +0100486 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000487 object_fun->set_initial_map(*object_function_map);
488 object_function_map->set_constructor(*object_fun);
489
490 global_context()->set_object_function(*object_fun);
491
492 // Allocate a new prototype for the object function.
Steve Block44f0eee2011-05-26 01:26:41 +0100493 Handle<JSObject> prototype = factory->NewJSObject(
494 isolate->object_function(),
495 TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +0000496
497 global_context()->set_initial_object_prototype(*prototype);
498 SetPrototype(object_fun, prototype);
499 object_function_map->
Steve Block44f0eee2011-05-26 01:26:41 +0100500 set_instance_descriptors(heap->empty_descriptor_array());
Steve Blocka7e24c12009-10-30 11:49:00 +0000501 }
502
503 // Allocate the empty function as the prototype for function ECMAScript
504 // 262 15.3.4.
Steve Block44f0eee2011-05-26 01:26:41 +0100505 Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
Steve Blocka7e24c12009-10-30 11:49:00 +0000506 Handle<JSFunction> empty_function =
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000507 factory->NewFunctionWithoutPrototype(symbol, CLASSIC_MODE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000508
Andrei Popescu31002712010-02-23 13:46:05 +0000509 // --- E m p t y ---
510 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +0100511 Handle<Code>(isolate->builtins()->builtin(
512 Builtins::kEmptyFunction));
Andrei Popescu31002712010-02-23 13:46:05 +0000513 empty_function->set_code(*code);
Iain Merrick75681382010-08-19 15:07:18 +0100514 empty_function->shared()->set_code(*code);
Steve Block44f0eee2011-05-26 01:26:41 +0100515 Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
516 Handle<Script> script = factory->NewScript(source);
Andrei Popescu31002712010-02-23 13:46:05 +0000517 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
518 empty_function->shared()->set_script(*script);
519 empty_function->shared()->set_start_position(0);
520 empty_function->shared()->set_end_position(source->length());
521 empty_function->shared()->DontAdaptArguments();
Steve Block44f0eee2011-05-26 01:26:41 +0100522
523 // Set prototypes for the function maps.
Andrei Popescu31002712010-02-23 13:46:05 +0000524 global_context()->function_map()->set_prototype(*empty_function);
525 global_context()->function_instance_map()->set_prototype(*empty_function);
Steve Block6ded16b2010-05-10 14:33:55 +0100526 global_context()->function_without_prototype_map()->
527 set_prototype(*empty_function);
Steve Block44f0eee2011-05-26 01:26:41 +0100528 function_instance_map_writable_prototype_->set_prototype(*empty_function);
Steve Blocka7e24c12009-10-30 11:49:00 +0000529
Andrei Popescu31002712010-02-23 13:46:05 +0000530 // Allocate the function map first and then patch the prototype later
Steve Block44f0eee2011-05-26 01:26:41 +0100531 Handle<Map> empty_fm = factory->CopyMapDropDescriptors(
Steve Block6ded16b2010-05-10 14:33:55 +0100532 function_without_prototype_map);
533 empty_fm->set_instance_descriptors(
Steve Block44f0eee2011-05-26 01:26:41 +0100534 function_without_prototype_map->instance_descriptors());
Andrei Popescu31002712010-02-23 13:46:05 +0000535 empty_fm->set_prototype(global_context()->object_function()->prototype());
536 empty_function->set_map(*empty_fm);
537 return empty_function;
538}
539
540
Steve Block44f0eee2011-05-26 01:26:41 +0100541Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
542 PrototypePropertyMode prototypeMode,
Ben Murdochc7cc0282012-03-05 14:35:55 +0000543 Handle<AccessorPair> arguments,
544 Handle<AccessorPair> caller) {
Steve Block44f0eee2011-05-26 01:26:41 +0100545 Handle<DescriptorArray> descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000546 factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
547 ? 4
548 : 5);
Steve Block44f0eee2011-05-26 01:26:41 +0100549 PropertyAttributes attributes = static_cast<PropertyAttributes>(
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000550 DONT_ENUM | DONT_DELETE);
551
552 DescriptorArray::WhitenessWitness witness(*descriptors);
Steve Block44f0eee2011-05-26 01:26:41 +0100553
554 { // length
Ben Murdoch257744e2011-11-30 15:57:28 +0000555 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
556 CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000557 descriptors->Set(0, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100558 }
559 { // name
Ben Murdoch257744e2011-11-30 15:57:28 +0000560 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
561 CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000562 descriptors->Set(1, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100563 }
564 { // arguments
Ben Murdoch257744e2011-11-30 15:57:28 +0000565 CallbacksDescriptor d(*factory()->arguments_symbol(),
566 *arguments,
567 attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000568 descriptors->Set(2, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100569 }
570 { // caller
Ben Murdoch257744e2011-11-30 15:57:28 +0000571 CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000572 descriptors->Set(3, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100573 }
574
575 // prototype
576 if (prototypeMode != DONT_ADD_PROTOTYPE) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000577 if (prototypeMode != ADD_WRITEABLE_PROTOTYPE) {
578 attributes = static_cast<PropertyAttributes>(attributes | READ_ONLY);
Steve Block44f0eee2011-05-26 01:26:41 +0100579 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000580 Handle<Foreign> foreign =
581 factory()->NewForeign(&Accessors::FunctionPrototype);
582 CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000583 descriptors->Set(4, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100584 }
585
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000586 descriptors->Sort(witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100587 return descriptors;
588}
589
590
591// ECMAScript 5th Edition, 13.2.3
Ben Murdoch257744e2011-11-30 15:57:28 +0000592Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
593 if (throw_type_error_function.is_null()) {
594 Handle<String> name = factory()->LookupAsciiSymbol("ThrowTypeError");
595 throw_type_error_function =
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000596 factory()->NewFunctionWithoutPrototype(name, CLASSIC_MODE);
Ben Murdoch257744e2011-11-30 15:57:28 +0000597 Handle<Code> code(isolate()->builtins()->builtin(
598 Builtins::kStrictModePoisonPill));
599 throw_type_error_function->set_map(
600 global_context()->function_map());
601 throw_type_error_function->set_code(*code);
602 throw_type_error_function->shared()->set_code(*code);
603 throw_type_error_function->shared()->DontAdaptArguments();
Steve Block053d10c2011-06-13 19:13:29 +0100604
Ben Murdochc7cc0282012-03-05 14:35:55 +0000605 JSObject::PreventExtensions(throw_type_error_function);
Ben Murdoch257744e2011-11-30 15:57:28 +0000606 }
607 return throw_type_error_function;
Steve Block44f0eee2011-05-26 01:26:41 +0100608}
609
610
611Handle<Map> Genesis::CreateStrictModeFunctionMap(
612 PrototypePropertyMode prototype_mode,
613 Handle<JSFunction> empty_function,
Ben Murdochc7cc0282012-03-05 14:35:55 +0000614 Handle<AccessorPair> arguments_callbacks,
615 Handle<AccessorPair> caller_callbacks) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000616 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Steve Block44f0eee2011-05-26 01:26:41 +0100617 Handle<DescriptorArray> descriptors =
618 ComputeStrictFunctionInstanceDescriptor(prototype_mode,
619 arguments_callbacks,
620 caller_callbacks);
621 map->set_instance_descriptors(*descriptors);
622 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
623 map->set_prototype(*empty_function);
624 return map;
625}
626
627
628void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
629 // Create the callbacks arrays for ThrowTypeError functions.
630 // The get/set callacks are filled in after the maps are created below.
Ben Murdoch257744e2011-11-30 15:57:28 +0000631 Factory* factory = empty->GetIsolate()->factory();
Ben Murdochc7cc0282012-03-05 14:35:55 +0000632 Handle<AccessorPair> arguments(factory->NewAccessorPair());
633 Handle<AccessorPair> caller(factory->NewAccessorPair());
Steve Block44f0eee2011-05-26 01:26:41 +0100634
635 // Allocate map for the strict mode function instances.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100636 Handle<Map> strict_mode_function_instance_map =
637 CreateStrictModeFunctionMap(
638 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100639 global_context()->set_strict_mode_function_instance_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100640 *strict_mode_function_instance_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100641
642 // Allocate map for the prototype-less strict mode instances.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100643 Handle<Map> strict_mode_function_without_prototype_map =
644 CreateStrictModeFunctionMap(
645 DONT_ADD_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100646 global_context()->set_strict_mode_function_without_prototype_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100647 *strict_mode_function_without_prototype_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100648
649 // Allocate map for the strict mode functions. This map is temporary, used
650 // only for processing of builtins.
651 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100652 Handle<Map> strict_mode_function_map =
653 CreateStrictModeFunctionMap(
654 ADD_READONLY_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100655 global_context()->set_strict_mode_function_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100656 *strict_mode_function_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100657
658 // The final map for the strict mode functions. Writeable prototype.
659 // This map is installed in MakeFunctionInstancePrototypeWritable.
660 strict_mode_function_instance_map_writable_prototype_ =
661 CreateStrictModeFunctionMap(
662 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
663
Ben Murdoch257744e2011-11-30 15:57:28 +0000664 // Create the ThrowTypeError function instance.
665 Handle<JSFunction> throw_function =
666 GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +0100667
Ben Murdochc7cc0282012-03-05 14:35:55 +0000668 // Complete the callbacks.
669 arguments->set_getter(*throw_function);
670 arguments->set_setter(*throw_function);
671 caller->set_getter(*throw_function);
672 caller->set_setter(*throw_function);
Steve Block44f0eee2011-05-26 01:26:41 +0100673}
674
675
Ben Murdochb0fe1622011-05-05 13:52:32 +0100676static void AddToWeakGlobalContextList(Context* context) {
677 ASSERT(context->IsGlobalContext());
Ben Murdoch257744e2011-11-30 15:57:28 +0000678 Heap* heap = context->GetIsolate()->heap();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100679#ifdef DEBUG
680 { // NOLINT
681 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
682 // Check that context is not in the list yet.
Steve Block44f0eee2011-05-26 01:26:41 +0100683 for (Object* current = heap->global_contexts_list();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100684 !current->IsUndefined();
685 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
686 ASSERT(current != context);
687 }
688 }
689#endif
Steve Block44f0eee2011-05-26 01:26:41 +0100690 context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
691 heap->set_global_contexts_list(context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100692}
693
694
Andrei Popescu31002712010-02-23 13:46:05 +0000695void Genesis::CreateRoots() {
696 // Allocate the global context FixedArray first and then patch the
697 // closure and extension object later (we need the empty function
698 // and the global object, but in order to create those, we need the
699 // global context).
Ben Murdoch257744e2011-11-30 15:57:28 +0000700 global_context_ = Handle<Context>::cast(isolate()->global_handles()->Create(
701 *factory()->NewGlobalContext()));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100702 AddToWeakGlobalContextList(*global_context_);
Ben Murdoch257744e2011-11-30 15:57:28 +0000703 isolate()->set_context(*global_context());
Andrei Popescu31002712010-02-23 13:46:05 +0000704
705 // Allocate the message listeners object.
706 {
707 v8::NeanderArray listeners;
708 global_context()->set_message_listeners(*listeners.value());
709 }
710}
711
712
713Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
714 v8::Handle<v8::ObjectTemplate> global_template,
715 Handle<Object> global_object,
716 Handle<GlobalObject>* inner_global_out) {
717 // The argument global_template aka data is an ObjectTemplateInfo.
718 // It has a constructor pointer that points at global_constructor which is a
719 // FunctionTemplateInfo.
720 // The global_constructor is used to create or reinitialize the global_proxy.
721 // The global_constructor also has a prototype_template pointer that points at
722 // js_global_template which is an ObjectTemplateInfo.
723 // That in turn has a constructor pointer that points at
724 // js_global_constructor which is a FunctionTemplateInfo.
725 // js_global_constructor is used to make js_global_function
726 // js_global_function is used to make the new inner_global.
727 //
728 // --- G l o b a l ---
729 // Step 1: Create a fresh inner JSGlobalObject.
730 Handle<JSFunction> js_global_function;
731 Handle<ObjectTemplateInfo> js_global_template;
732 if (!global_template.IsEmpty()) {
733 // Get prototype template of the global_template.
734 Handle<ObjectTemplateInfo> data =
735 v8::Utils::OpenHandle(*global_template);
736 Handle<FunctionTemplateInfo> global_constructor =
737 Handle<FunctionTemplateInfo>(
738 FunctionTemplateInfo::cast(data->constructor()));
739 Handle<Object> proto_template(global_constructor->prototype_template());
740 if (!proto_template->IsUndefined()) {
741 js_global_template =
742 Handle<ObjectTemplateInfo>::cast(proto_template);
743 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000744 }
745
Andrei Popescu31002712010-02-23 13:46:05 +0000746 if (js_global_template.is_null()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000747 Handle<String> name = Handle<String>(heap()->empty_symbol());
748 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
Steve Block44f0eee2011-05-26 01:26:41 +0100749 Builtins::kIllegal));
Andrei Popescu31002712010-02-23 13:46:05 +0000750 js_global_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000751 factory()->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
752 JSGlobalObject::kSize, code, true);
Andrei Popescu31002712010-02-23 13:46:05 +0000753 // Change the constructor property of the prototype of the
754 // hidden global function to refer to the Object function.
755 Handle<JSObject> prototype =
756 Handle<JSObject>(
757 JSObject::cast(js_global_function->instance_prototype()));
Ben Murdochc7cc0282012-03-05 14:35:55 +0000758 CHECK_NOT_EMPTY_HANDLE(isolate(),
759 JSObject::SetLocalPropertyIgnoreAttributes(
760 prototype, factory()->constructor_symbol(),
761 isolate()->object_function(), NONE));
Andrei Popescu31002712010-02-23 13:46:05 +0000762 } else {
763 Handle<FunctionTemplateInfo> js_global_constructor(
764 FunctionTemplateInfo::cast(js_global_template->constructor()));
765 js_global_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000766 factory()->CreateApiFunction(js_global_constructor,
767 factory()->InnerGlobalObject);
Steve Blocka7e24c12009-10-30 11:49:00 +0000768 }
769
Andrei Popescu31002712010-02-23 13:46:05 +0000770 js_global_function->initial_map()->set_is_hidden_prototype();
771 Handle<GlobalObject> inner_global =
Ben Murdoch257744e2011-11-30 15:57:28 +0000772 factory()->NewGlobalObject(js_global_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000773 if (inner_global_out != NULL) {
774 *inner_global_out = inner_global;
775 }
776
777 // Step 2: create or re-initialize the global proxy object.
778 Handle<JSFunction> global_proxy_function;
779 if (global_template.IsEmpty()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000780 Handle<String> name = Handle<String>(heap()->empty_symbol());
781 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
Steve Block44f0eee2011-05-26 01:26:41 +0100782 Builtins::kIllegal));
Andrei Popescu31002712010-02-23 13:46:05 +0000783 global_proxy_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000784 factory()->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
785 JSGlobalProxy::kSize, code, true);
Andrei Popescu31002712010-02-23 13:46:05 +0000786 } else {
787 Handle<ObjectTemplateInfo> data =
788 v8::Utils::OpenHandle(*global_template);
789 Handle<FunctionTemplateInfo> global_constructor(
790 FunctionTemplateInfo::cast(data->constructor()));
791 global_proxy_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000792 factory()->CreateApiFunction(global_constructor,
793 factory()->OuterGlobalObject);
Andrei Popescu31002712010-02-23 13:46:05 +0000794 }
795
Ben Murdoch257744e2011-11-30 15:57:28 +0000796 Handle<String> global_name = factory()->LookupAsciiSymbol("global");
Andrei Popescu31002712010-02-23 13:46:05 +0000797 global_proxy_function->shared()->set_instance_class_name(*global_name);
798 global_proxy_function->initial_map()->set_is_access_check_needed(true);
799
800 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
801 // Return the global proxy.
802
803 if (global_object.location() != NULL) {
804 ASSERT(global_object->IsJSGlobalProxy());
805 return ReinitializeJSGlobalProxy(
806 global_proxy_function,
807 Handle<JSGlobalProxy>::cast(global_object));
808 } else {
809 return Handle<JSGlobalProxy>::cast(
Ben Murdoch257744e2011-11-30 15:57:28 +0000810 factory()->NewJSObject(global_proxy_function, TENURED));
Andrei Popescu31002712010-02-23 13:46:05 +0000811 }
812}
813
814
815void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
816 Handle<JSGlobalProxy> global_proxy) {
817 // Set the global context for the global object.
818 inner_global->set_global_context(*global_context());
819 inner_global->set_global_receiver(*global_proxy);
820 global_proxy->set_context(*global_context());
821 global_context()->set_global_proxy(*global_proxy);
822}
823
824
Andrei Popescu402d9372010-02-26 13:31:12 +0000825void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
826 Handle<GlobalObject> inner_global_from_snapshot(
827 GlobalObject::cast(global_context_->extension()));
828 Handle<JSBuiltinsObject> builtins_global(global_context_->builtins());
829 global_context_->set_extension(*inner_global);
830 global_context_->set_global(*inner_global);
831 global_context_->set_security_token(*inner_global);
832 static const PropertyAttributes attributes =
833 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
834 ForceSetProperty(builtins_global,
Ben Murdoch257744e2011-11-30 15:57:28 +0000835 factory()->LookupAsciiSymbol("global"),
Andrei Popescu402d9372010-02-26 13:31:12 +0000836 inner_global,
837 attributes);
Ben Murdochc7cc0282012-03-05 14:35:55 +0000838 // Set up the reference from the global object to the builtins object.
Andrei Popescu402d9372010-02-26 13:31:12 +0000839 JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
840 TransferNamedProperties(inner_global_from_snapshot, inner_global);
841 TransferIndexedProperties(inner_global_from_snapshot, inner_global);
842}
843
844
845// This is only called if we are not using snapshots. The equivalent
846// work in the snapshot case is done in HookUpInnerGlobal.
Andrei Popescu31002712010-02-23 13:46:05 +0000847void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
848 Handle<JSFunction> empty_function) {
849 // --- G l o b a l C o n t e x t ---
850 // Use the empty function as closure (no scope info).
851 global_context()->set_closure(*empty_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000852 global_context()->set_previous(NULL);
853 // Set extension and global object.
854 global_context()->set_extension(*inner_global);
855 global_context()->set_global(*inner_global);
856 // Security setup: Set the security token of the global object to
857 // its the inner global. This makes the security check between two
858 // different contexts fail by default even in case of global
859 // object reinitialization.
860 global_context()->set_security_token(*inner_global);
861
Ben Murdoch257744e2011-11-30 15:57:28 +0000862 Isolate* isolate = inner_global->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100863 Factory* factory = isolate->factory();
864 Heap* heap = isolate->heap();
865
866 Handle<String> object_name = Handle<String>(heap->Object_symbol());
Ben Murdochc7cc0282012-03-05 14:35:55 +0000867 CHECK_NOT_EMPTY_HANDLE(isolate,
868 JSObject::SetLocalPropertyIgnoreAttributes(
869 inner_global, object_name,
870 isolate->object_function(), DONT_ENUM));
Andrei Popescu31002712010-02-23 13:46:05 +0000871
Steve Blocka7e24c12009-10-30 11:49:00 +0000872 Handle<JSObject> global = Handle<JSObject>(global_context()->global());
873
874 // Install global Function object
875 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100876 empty_function, Builtins::kIllegal, true); // ECMA native.
Steve Blocka7e24c12009-10-30 11:49:00 +0000877
878 { // --- A r r a y ---
879 Handle<JSFunction> array_function =
880 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100881 isolate->initial_object_prototype(),
882 Builtins::kArrayCode, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000883 array_function->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +0100884 isolate->builtins()->builtin(Builtins::kArrayConstructCode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000885 array_function->shared()->DontAdaptArguments();
886
887 // This seems a bit hackish, but we need to make sure Array.length
888 // is 1.
889 array_function->shared()->set_length(1);
890 Handle<DescriptorArray> array_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000891 factory->CopyAppendForeignDescriptor(
Steve Block44f0eee2011-05-26 01:26:41 +0100892 factory->empty_descriptor_array(),
893 factory->length_symbol(),
Ben Murdoch257744e2011-11-30 15:57:28 +0000894 factory->NewForeign(&Accessors::ArrayLength),
Steve Blocka7e24c12009-10-30 11:49:00 +0000895 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
896
897 // Cache the fast JavaScript array map
898 global_context()->set_js_array_map(array_function->initial_map());
899 global_context()->js_array_map()->set_instance_descriptors(
900 *array_descriptors);
901 // array_function is used internally. JS code creating array object should
902 // search for the 'Array' property on the global object and use that one
903 // as the constructor. 'Array' property on a global object can be
904 // overwritten by JS code.
905 global_context()->set_array_function(*array_function);
906 }
907
908 { // --- N u m b e r ---
909 Handle<JSFunction> number_fun =
910 InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100911 isolate->initial_object_prototype(),
912 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000913 global_context()->set_number_function(*number_fun);
914 }
915
916 { // --- B o o l e a n ---
917 Handle<JSFunction> boolean_fun =
918 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100919 isolate->initial_object_prototype(),
920 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000921 global_context()->set_boolean_function(*boolean_fun);
922 }
923
924 { // --- S t r i n g ---
925 Handle<JSFunction> string_fun =
926 InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100927 isolate->initial_object_prototype(),
928 Builtins::kIllegal, true);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100929 string_fun->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +0100930 isolate->builtins()->builtin(Builtins::kStringConstructCode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000931 global_context()->set_string_function(*string_fun);
932 // Add 'length' property to strings.
933 Handle<DescriptorArray> string_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000934 factory->CopyAppendForeignDescriptor(
Steve Block44f0eee2011-05-26 01:26:41 +0100935 factory->empty_descriptor_array(),
936 factory->length_symbol(),
Ben Murdoch257744e2011-11-30 15:57:28 +0000937 factory->NewForeign(&Accessors::StringLength),
Steve Blocka7e24c12009-10-30 11:49:00 +0000938 static_cast<PropertyAttributes>(DONT_ENUM |
939 DONT_DELETE |
940 READ_ONLY));
941
942 Handle<Map> string_map =
943 Handle<Map>(global_context()->string_function()->initial_map());
944 string_map->set_instance_descriptors(*string_descriptors);
945 }
946
947 { // --- D a t e ---
948 // Builtin functions for Date.prototype.
949 Handle<JSFunction> date_fun =
950 InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100951 isolate->initial_object_prototype(),
952 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000953
954 global_context()->set_date_function(*date_fun);
955 }
956
957
958 { // -- R e g E x p
959 // Builtin functions for RegExp.prototype.
960 Handle<JSFunction> regexp_fun =
961 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100962 isolate->initial_object_prototype(),
963 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000964 global_context()->set_regexp_function(*regexp_fun);
Steve Block6ded16b2010-05-10 14:33:55 +0100965
966 ASSERT(regexp_fun->has_initial_map());
967 Handle<Map> initial_map(regexp_fun->initial_map());
968
969 ASSERT_EQ(0, initial_map->inobject_properties());
970
Steve Block44f0eee2011-05-26 01:26:41 +0100971 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000972 DescriptorArray::WhitenessWitness witness(*descriptors);
Steve Block6ded16b2010-05-10 14:33:55 +0100973 PropertyAttributes final =
974 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
975 int enum_index = 0;
976 {
977 // ECMA-262, section 15.10.7.1.
Steve Block44f0eee2011-05-26 01:26:41 +0100978 FieldDescriptor field(heap->source_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100979 JSRegExp::kSourceFieldIndex,
980 final,
981 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000982 descriptors->Set(0, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +0100983 }
984 {
985 // ECMA-262, section 15.10.7.2.
Steve Block44f0eee2011-05-26 01:26:41 +0100986 FieldDescriptor field(heap->global_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100987 JSRegExp::kGlobalFieldIndex,
988 final,
989 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000990 descriptors->Set(1, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +0100991 }
992 {
993 // ECMA-262, section 15.10.7.3.
Steve Block44f0eee2011-05-26 01:26:41 +0100994 FieldDescriptor field(heap->ignore_case_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100995 JSRegExp::kIgnoreCaseFieldIndex,
996 final,
997 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000998 descriptors->Set(2, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +0100999 }
1000 {
1001 // ECMA-262, section 15.10.7.4.
Steve Block44f0eee2011-05-26 01:26:41 +01001002 FieldDescriptor field(heap->multiline_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001003 JSRegExp::kMultilineFieldIndex,
1004 final,
1005 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001006 descriptors->Set(3, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001007 }
1008 {
1009 // ECMA-262, section 15.10.7.5.
1010 PropertyAttributes writable =
1011 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
Steve Block44f0eee2011-05-26 01:26:41 +01001012 FieldDescriptor field(heap->last_index_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001013 JSRegExp::kLastIndexFieldIndex,
1014 writable,
1015 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001016 descriptors->Set(4, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001017 }
1018 descriptors->SetNextEnumerationIndex(enum_index);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001019 descriptors->Sort(witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001020
1021 initial_map->set_inobject_properties(5);
1022 initial_map->set_pre_allocated_property_fields(5);
1023 initial_map->set_unused_property_fields(0);
1024 initial_map->set_instance_size(
1025 initial_map->instance_size() + 5 * kPointerSize);
1026 initial_map->set_instance_descriptors(*descriptors);
Iain Merrick75681382010-08-19 15:07:18 +01001027 initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001028
1029 // RegExp prototype object is itself a RegExp.
1030 Handle<Map> proto_map = factory->CopyMapDropTransitions(initial_map);
1031 proto_map->set_prototype(global_context()->initial_object_prototype());
1032 Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
1033 proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
1034 heap->empty_string());
1035 proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
1036 heap->false_value());
1037 proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
1038 heap->false_value());
1039 proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex,
1040 heap->false_value());
1041 proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
1042 Smi::FromInt(0),
1043 SKIP_WRITE_BARRIER); // It's a Smi.
1044 initial_map->set_prototype(*proto);
1045 factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
1046 JSRegExp::IRREGEXP, factory->empty_string(),
1047 JSRegExp::Flags(0), 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001048 }
1049
1050 { // -- J S O N
Steve Block44f0eee2011-05-26 01:26:41 +01001051 Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
Ben Murdochc7cc0282012-03-05 14:35:55 +00001052 Handle<JSFunction> cons = factory->NewFunction(name,
1053 factory->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001054 cons->SetInstancePrototype(global_context()->initial_object_prototype());
1055 cons->SetInstanceClassName(*name);
Steve Block44f0eee2011-05-26 01:26:41 +01001056 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001057 ASSERT(json_object->IsJSObject());
Ben Murdochc7cc0282012-03-05 14:35:55 +00001058 CHECK_NOT_EMPTY_HANDLE(isolate,
1059 JSObject::SetLocalPropertyIgnoreAttributes(
1060 global, name, json_object, DONT_ENUM));
Steve Blocka7e24c12009-10-30 11:49:00 +00001061 global_context()->set_json_object(*json_object);
1062 }
1063
1064 { // --- arguments_boilerplate_
1065 // Make sure we can recognize argument objects at runtime.
1066 // This is done by introducing an anonymous function with
1067 // class_name equals 'Arguments'.
Steve Block44f0eee2011-05-26 01:26:41 +01001068 Handle<String> symbol = factory->LookupAsciiSymbol("Arguments");
1069 Handle<Code> code = Handle<Code>(
1070 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001071 Handle<JSObject> prototype =
1072 Handle<JSObject>(
1073 JSObject::cast(global_context()->object_function()->prototype()));
1074
1075 Handle<JSFunction> function =
Steve Block44f0eee2011-05-26 01:26:41 +01001076 factory->NewFunctionWithPrototype(symbol,
Steve Blocka7e24c12009-10-30 11:49:00 +00001077 JS_OBJECT_TYPE,
1078 JSObject::kHeaderSize,
1079 prototype,
1080 code,
1081 false);
1082 ASSERT(!function->has_initial_map());
1083 function->shared()->set_instance_class_name(*symbol);
1084 function->shared()->set_expected_nof_properties(2);
Steve Block44f0eee2011-05-26 01:26:41 +01001085 Handle<JSObject> result = factory->NewJSObject(function);
Steve Blocka7e24c12009-10-30 11:49:00 +00001086
1087 global_context()->set_arguments_boilerplate(*result);
Steve Block44f0eee2011-05-26 01:26:41 +01001088 // Note: length must be added as the first property and
1089 // callee must be added as the second property.
Ben Murdochc7cc0282012-03-05 14:35:55 +00001090 CHECK_NOT_EMPTY_HANDLE(isolate,
1091 JSObject::SetLocalPropertyIgnoreAttributes(
1092 result, factory->length_symbol(),
1093 factory->undefined_value(), DONT_ENUM));
1094 CHECK_NOT_EMPTY_HANDLE(isolate,
1095 JSObject::SetLocalPropertyIgnoreAttributes(
1096 result, factory->callee_symbol(),
1097 factory->undefined_value(), DONT_ENUM));
Steve Blocka7e24c12009-10-30 11:49:00 +00001098
1099#ifdef DEBUG
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001100 LookupResult lookup(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01001101 result->LocalLookup(heap->callee_symbol(), &lookup);
Ben Murdochc7cc0282012-03-05 14:35:55 +00001102 ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001103 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001104
Steve Block44f0eee2011-05-26 01:26:41 +01001105 result->LocalLookup(heap->length_symbol(), &lookup);
Ben Murdochc7cc0282012-03-05 14:35:55 +00001106 ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001107 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001108
Steve Block44f0eee2011-05-26 01:26:41 +01001109 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
1110 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1111
1112 // Check the state of the object.
1113 ASSERT(result->HasFastProperties());
1114 ASSERT(result->HasFastElements());
1115#endif
1116 }
1117
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001118 { // --- aliased_arguments_boilerplate_
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001119 // Set up a well-formed parameter map to make assertions happy.
1120 Handle<FixedArray> elements = factory->NewFixedArray(2);
1121 elements->set_map(heap->non_strict_arguments_elements_map());
1122 Handle<FixedArray> array;
1123 array = factory->NewFixedArray(0);
1124 elements->set(0, *array);
1125 array = factory->NewFixedArray(0);
1126 elements->set(1, *array);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001127
1128 Handle<Map> old_map(global_context()->arguments_boilerplate()->map());
1129 Handle<Map> new_map = factory->CopyMapDropTransitions(old_map);
1130 new_map->set_pre_allocated_property_fields(2);
1131 Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
1132 // Set elements kind after allocating the object because
1133 // NewJSObjectFromMap assumes a fast elements map.
1134 new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001135 result->set_elements(*elements);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001136 ASSERT(result->HasNonStrictArgumentsElements());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001137 global_context()->set_aliased_arguments_boilerplate(*result);
1138 }
1139
Steve Block44f0eee2011-05-26 01:26:41 +01001140 { // --- strict mode arguments boilerplate
1141 const PropertyAttributes attributes =
1142 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1143
1144 // Create the ThrowTypeError functions.
Ben Murdochc7cc0282012-03-05 14:35:55 +00001145 Handle<AccessorPair> callee = factory->NewAccessorPair();
1146 Handle<AccessorPair> caller = factory->NewAccessorPair();
Steve Block44f0eee2011-05-26 01:26:41 +01001147
Ben Murdoch257744e2011-11-30 15:57:28 +00001148 Handle<JSFunction> throw_function =
1149 GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +01001150
1151 // Install the ThrowTypeError functions.
Ben Murdochc7cc0282012-03-05 14:35:55 +00001152 callee->set_getter(*throw_function);
1153 callee->set_setter(*throw_function);
1154 caller->set_getter(*throw_function);
1155 caller->set_setter(*throw_function);
Steve Block44f0eee2011-05-26 01:26:41 +01001156
1157 // Create the descriptor array for the arguments object.
1158 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001159 DescriptorArray::WhitenessWitness witness(*descriptors);
Steve Block44f0eee2011-05-26 01:26:41 +01001160 { // length
1161 FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001162 descriptors->Set(0, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +01001163 }
1164 { // callee
1165 CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001166 descriptors->Set(1, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +01001167 }
1168 { // caller
1169 CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001170 descriptors->Set(2, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +01001171 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001172 descriptors->Sort(witness);
Steve Block44f0eee2011-05-26 01:26:41 +01001173
1174 // Create the map. Allocate one in-object field for length.
1175 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1176 Heap::kArgumentsObjectSizeStrict);
1177 map->set_instance_descriptors(*descriptors);
1178 map->set_function_with_prototype(true);
1179 map->set_prototype(global_context()->object_function()->prototype());
1180 map->set_pre_allocated_property_fields(1);
1181 map->set_inobject_properties(1);
1182
1183 // Copy constructor from the non-strict arguments boilerplate.
1184 map->set_constructor(
1185 global_context()->arguments_boilerplate()->map()->constructor());
1186
1187 // Allocate the arguments boilerplate object.
1188 Handle<JSObject> result = factory->NewJSObjectFromMap(map);
1189 global_context()->set_strict_mode_arguments_boilerplate(*result);
1190
1191 // Add length property only for strict mode boilerplate.
Ben Murdochc7cc0282012-03-05 14:35:55 +00001192 CHECK_NOT_EMPTY_HANDLE(isolate,
1193 JSObject::SetLocalPropertyIgnoreAttributes(
1194 result, factory->length_symbol(),
1195 factory->undefined_value(), DONT_ENUM));
Steve Block44f0eee2011-05-26 01:26:41 +01001196
1197#ifdef DEBUG
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001198 LookupResult lookup(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01001199 result->LocalLookup(heap->length_symbol(), &lookup);
Ben Murdochc7cc0282012-03-05 14:35:55 +00001200 ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001201 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
1202
1203 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001204
1205 // Check the state of the object.
1206 ASSERT(result->HasFastProperties());
1207 ASSERT(result->HasFastElements());
1208#endif
1209 }
1210
1211 { // --- context extension
1212 // Create a function for the context extension objects.
Steve Block44f0eee2011-05-26 01:26:41 +01001213 Handle<Code> code = Handle<Code>(
1214 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001215 Handle<JSFunction> context_extension_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001216 factory->NewFunction(factory->empty_symbol(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001217 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1218 JSObject::kHeaderSize,
1219 code,
1220 true);
1221
Steve Block44f0eee2011-05-26 01:26:41 +01001222 Handle<String> name = factory->LookupAsciiSymbol("context_extension");
Steve Blocka7e24c12009-10-30 11:49:00 +00001223 context_extension_fun->shared()->set_instance_class_name(*name);
1224 global_context()->set_context_extension_function(*context_extension_fun);
1225 }
1226
1227
1228 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001229 // Set up the call-as-function delegate.
Steve Blocka7e24c12009-10-30 11:49:00 +00001230 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +01001231 Handle<Code>(isolate->builtins()->builtin(
1232 Builtins::kHandleApiCallAsFunction));
Steve Blocka7e24c12009-10-30 11:49:00 +00001233 Handle<JSFunction> delegate =
Steve Block44f0eee2011-05-26 01:26:41 +01001234 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001235 JSObject::kHeaderSize, code, true);
1236 global_context()->set_call_as_function_delegate(*delegate);
1237 delegate->shared()->DontAdaptArguments();
1238 }
1239
1240 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001241 // Set up the call-as-constructor delegate.
Steve Blocka7e24c12009-10-30 11:49:00 +00001242 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +01001243 Handle<Code>(isolate->builtins()->builtin(
1244 Builtins::kHandleApiCallAsConstructor));
Steve Blocka7e24c12009-10-30 11:49:00 +00001245 Handle<JSFunction> delegate =
Steve Block44f0eee2011-05-26 01:26:41 +01001246 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001247 JSObject::kHeaderSize, code, true);
1248 global_context()->set_call_as_constructor_delegate(*delegate);
1249 delegate->shared()->DontAdaptArguments();
1250 }
1251
Steve Blocka7e24c12009-10-30 11:49:00 +00001252 // Initialize the out of memory slot.
Steve Block44f0eee2011-05-26 01:26:41 +01001253 global_context()->set_out_of_memory(heap->false_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001254
1255 // Initialize the data slot.
Steve Block44f0eee2011-05-26 01:26:41 +01001256 global_context()->set_data(heap->undefined_value());
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001257
1258 {
1259 // Initialize the random seed slot.
1260 Handle<ByteArray> zeroed_byte_array(
1261 factory->NewByteArray(kRandomStateSize));
1262 global_context()->set_random_seed(*zeroed_byte_array);
1263 memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize);
1264 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001265}
1266
1267
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001268void Genesis::InitializeExperimentalGlobal() {
1269 Handle<JSObject> global = Handle<JSObject>(global_context()->global());
1270
1271 // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001272 // longer need to live behind a flag, so functions get added to the snapshot.
1273 if (FLAG_harmony_collections) {
1274 { // -- S e t
1275 Handle<JSObject> prototype =
1276 factory()->NewJSObject(isolate()->object_function(), TENURED);
1277 InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize,
1278 prototype, Builtins::kIllegal, true);
1279 }
1280 { // -- M a p
1281 Handle<JSObject> prototype =
1282 factory()->NewJSObject(isolate()->object_function(), TENURED);
1283 InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize,
1284 prototype, Builtins::kIllegal, true);
1285 }
1286 { // -- W e a k M a p
1287 Handle<JSObject> prototype =
1288 factory()->NewJSObject(isolate()->object_function(), TENURED);
1289 InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1290 prototype, Builtins::kIllegal, true);
1291 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001292 }
1293}
1294
1295
Ben Murdoch257744e2011-11-30 15:57:28 +00001296bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001297 Vector<const char> name = Natives::GetScriptName(index);
Steve Block44f0eee2011-05-26 01:26:41 +01001298 Handle<String> source_code =
Ben Murdoch257744e2011-11-30 15:57:28 +00001299 isolate->bootstrapper()->NativesSourceLookup(index);
1300 return CompileNative(name, source_code);
1301}
1302
1303
1304bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
1305 Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1306 Factory* factory = isolate->factory();
1307 Handle<String> source_code =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001308 factory->NewStringFromAscii(
1309 ExperimentalNatives::GetRawScriptSource(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00001310 return CompileNative(name, source_code);
1311}
1312
1313
1314bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
1315 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00001316 Isolate* isolate = source->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +00001317#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +01001318 isolate->debugger()->set_compiling_natives(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001319#endif
Andrei Popescu31002712010-02-23 13:46:05 +00001320 bool result = CompileScriptCached(name,
1321 source,
1322 NULL,
1323 NULL,
Steve Block44f0eee2011-05-26 01:26:41 +01001324 Handle<Context>(isolate->context()),
Andrei Popescu31002712010-02-23 13:46:05 +00001325 true);
Steve Block44f0eee2011-05-26 01:26:41 +01001326 ASSERT(isolate->has_pending_exception() != result);
1327 if (!result) isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00001328#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +01001329 isolate->debugger()->set_compiling_natives(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001330#endif
1331 return result;
1332}
1333
1334
1335bool Genesis::CompileScriptCached(Vector<const char> name,
1336 Handle<String> source,
1337 SourceCodeCache* cache,
1338 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +00001339 Handle<Context> top_context,
Steve Blocka7e24c12009-10-30 11:49:00 +00001340 bool use_runtime_context) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001341 Factory* factory = source->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001342 HandleScope scope;
Steve Block6ded16b2010-05-10 14:33:55 +01001343 Handle<SharedFunctionInfo> function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +00001344
1345 // If we can't find the function in the cache, we compile a new
1346 // function and insert it into the cache.
Steve Block6ded16b2010-05-10 14:33:55 +01001347 if (cache == NULL || !cache->Lookup(name, &function_info)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001348 ASSERT(source->IsAsciiRepresentation());
Steve Block44f0eee2011-05-26 01:26:41 +01001349 Handle<String> script_name = factory->NewStringFromUtf8(name);
Steve Block6ded16b2010-05-10 14:33:55 +01001350 function_info = Compiler::Compile(
Andrei Popescu31002712010-02-23 13:46:05 +00001351 source,
1352 script_name,
1353 0,
1354 0,
1355 extension,
1356 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001357 Handle<String>::null(),
Andrei Popescu31002712010-02-23 13:46:05 +00001358 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001359 if (function_info.is_null()) return false;
1360 if (cache != NULL) cache->Add(name, function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +00001361 }
1362
Ben Murdochc7cc0282012-03-05 14:35:55 +00001363 // Set up the function context. Conceptually, we should clone the
Steve Blocka7e24c12009-10-30 11:49:00 +00001364 // function before overwriting the context but since we're in a
1365 // single-threaded environment it is not strictly necessary.
Andrei Popescu31002712010-02-23 13:46:05 +00001366 ASSERT(top_context->IsGlobalContext());
Steve Blocka7e24c12009-10-30 11:49:00 +00001367 Handle<Context> context =
1368 Handle<Context>(use_runtime_context
Andrei Popescu31002712010-02-23 13:46:05 +00001369 ? Handle<Context>(top_context->runtime_context())
1370 : top_context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001371 Handle<JSFunction> fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001372 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001373
Leon Clarke4515c472010-02-03 11:58:03 +00001374 // Call function using either the runtime object or the global
Steve Blocka7e24c12009-10-30 11:49:00 +00001375 // object as the receiver. Provide no parameters.
1376 Handle<Object> receiver =
1377 Handle<Object>(use_runtime_context
Andrei Popescu31002712010-02-23 13:46:05 +00001378 ? top_context->builtins()
1379 : top_context->global());
Steve Blocka7e24c12009-10-30 11:49:00 +00001380 bool has_pending_exception;
Ben Murdoch257744e2011-11-30 15:57:28 +00001381 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00001382 if (has_pending_exception) return false;
Andrei Popescu402d9372010-02-26 13:31:12 +00001383 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00001384}
1385
1386
Ben Murdoch257744e2011-11-30 15:57:28 +00001387#define INSTALL_NATIVE(Type, name, var) \
1388 Handle<String> var##_name = factory()->LookupAsciiSymbol(name); \
1389 Object* var##_native = \
1390 global_context()->builtins()->GetPropertyNoExceptionThrown( \
1391 *var##_name); \
Ben Murdoch8b112d22011-06-08 16:22:53 +01001392 global_context()->set_##var(Type::cast(var##_native));
Steve Blocka7e24c12009-10-30 11:49:00 +00001393
Steve Block44f0eee2011-05-26 01:26:41 +01001394
Steve Blocka7e24c12009-10-30 11:49:00 +00001395void Genesis::InstallNativeFunctions() {
1396 HandleScope scope;
1397 INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
1398 INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
1399 INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
1400 INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
1401 INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
1402 INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
1403 INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
1404 INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
Leon Clarkee46be812010-01-19 14:06:41 +00001405 INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001406 INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
1407 INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
1408 configure_instance_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001409 INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
1410 INSTALL_NATIVE(JSObject, "functionCache", function_cache);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001411 INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
1412 to_complete_property_descriptor);
Steve Blocka7e24c12009-10-30 11:49:00 +00001413}
1414
Ben Murdoch257744e2011-11-30 15:57:28 +00001415void Genesis::InstallExperimentalNativeFunctions() {
1416 if (FLAG_harmony_proxies) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001417 INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
Ben Murdoch257744e2011-11-30 15:57:28 +00001418 INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001419 INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001420 INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
Ben Murdoch257744e2011-11-30 15:57:28 +00001421 }
1422}
1423
Steve Blocka7e24c12009-10-30 11:49:00 +00001424#undef INSTALL_NATIVE
1425
1426
1427bool Genesis::InstallNatives() {
1428 HandleScope scope;
1429
1430 // Create a function for the builtins object. Allocate space for the
1431 // JavaScript builtins, a reference to the builtins object
1432 // (itself) and a reference to the global_context directly in the object.
Steve Block44f0eee2011-05-26 01:26:41 +01001433 Handle<Code> code = Handle<Code>(
Ben Murdoch257744e2011-11-30 15:57:28 +00001434 isolate()->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001435 Handle<JSFunction> builtins_fun =
Ben Murdoch257744e2011-11-30 15:57:28 +00001436 factory()->NewFunction(factory()->empty_symbol(),
1437 JS_BUILTINS_OBJECT_TYPE,
1438 JSBuiltinsObject::kSize, code, true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001439
Ben Murdoch257744e2011-11-30 15:57:28 +00001440 Handle<String> name = factory()->LookupAsciiSymbol("builtins");
Steve Blocka7e24c12009-10-30 11:49:00 +00001441 builtins_fun->shared()->set_instance_class_name(*name);
1442
1443 // Allocate the builtins object.
1444 Handle<JSBuiltinsObject> builtins =
Ben Murdoch257744e2011-11-30 15:57:28 +00001445 Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
Steve Blocka7e24c12009-10-30 11:49:00 +00001446 builtins->set_builtins(*builtins);
1447 builtins->set_global_context(*global_context());
1448 builtins->set_global_receiver(*builtins);
1449
Ben Murdochc7cc0282012-03-05 14:35:55 +00001450 // Set up the 'global' properties of the builtins object. The
Steve Blocka7e24c12009-10-30 11:49:00 +00001451 // 'global' property that refers to the global object is the only
1452 // way to get from code running in the builtins context to the
1453 // global object.
1454 static const PropertyAttributes attributes =
1455 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
Ben Murdoch257744e2011-11-30 15:57:28 +00001456 Handle<String> global_symbol = factory()->LookupAsciiSymbol("global");
Steve Block1e0659c2011-05-24 12:43:12 +01001457 Handle<Object> global_obj(global_context()->global());
Ben Murdochc7cc0282012-03-05 14:35:55 +00001458 CHECK_NOT_EMPTY_HANDLE(isolate(),
1459 JSObject::SetLocalPropertyIgnoreAttributes(
1460 builtins, global_symbol, global_obj, attributes));
Steve Blocka7e24c12009-10-30 11:49:00 +00001461
Ben Murdochc7cc0282012-03-05 14:35:55 +00001462 // Set up the reference from the global object to the builtins object.
Steve Blocka7e24c12009-10-30 11:49:00 +00001463 JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
1464
1465 // Create a bridge function that has context in the global context.
1466 Handle<JSFunction> bridge =
Ben Murdoch257744e2011-11-30 15:57:28 +00001467 factory()->NewFunction(factory()->empty_symbol(),
1468 factory()->undefined_value());
1469 ASSERT(bridge->context() == *isolate()->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001470
1471 // Allocate the builtins context.
1472 Handle<Context> context =
Ben Murdoch257744e2011-11-30 15:57:28 +00001473 factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
Steve Blocka7e24c12009-10-30 11:49:00 +00001474 context->set_global(*builtins); // override builtins global object
1475
1476 global_context()->set_runtime_context(*context);
1477
1478 { // -- S c r i p t
1479 // Builtin functions for Script.
1480 Handle<JSFunction> script_fun =
1481 InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001482 isolate()->initial_object_prototype(),
Steve Block44f0eee2011-05-26 01:26:41 +01001483 Builtins::kIllegal, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001484 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001485 factory()->NewJSObject(isolate()->object_function(), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001486 SetPrototype(script_fun, prototype);
1487 global_context()->set_script_function(*script_fun);
1488
1489 // Add 'source' and 'data' property to scripts.
1490 PropertyAttributes common_attributes =
1491 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Ben Murdoch257744e2011-11-30 15:57:28 +00001492 Handle<Foreign> foreign_source =
1493 factory()->NewForeign(&Accessors::ScriptSource);
Steve Blocka7e24c12009-10-30 11:49:00 +00001494 Handle<DescriptorArray> script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001495 factory()->CopyAppendForeignDescriptor(
1496 factory()->empty_descriptor_array(),
1497 factory()->LookupAsciiSymbol("source"),
1498 foreign_source,
Steve Blocka7e24c12009-10-30 11:49:00 +00001499 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001500 Handle<Foreign> foreign_name =
1501 factory()->NewForeign(&Accessors::ScriptName);
Steve Blocka7e24c12009-10-30 11:49:00 +00001502 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001503 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001504 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001505 factory()->LookupAsciiSymbol("name"),
1506 foreign_name,
Steve Blocka7e24c12009-10-30 11:49:00 +00001507 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001508 Handle<Foreign> foreign_id = factory()->NewForeign(&Accessors::ScriptId);
Steve Blocka7e24c12009-10-30 11:49:00 +00001509 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001510 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001511 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001512 factory()->LookupAsciiSymbol("id"),
1513 foreign_id,
Steve Blocka7e24c12009-10-30 11:49:00 +00001514 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001515 Handle<Foreign> foreign_line_offset =
1516 factory()->NewForeign(&Accessors::ScriptLineOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001517 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001518 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001519 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001520 factory()->LookupAsciiSymbol("line_offset"),
1521 foreign_line_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +00001522 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001523 Handle<Foreign> foreign_column_offset =
1524 factory()->NewForeign(&Accessors::ScriptColumnOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001525 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001526 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001527 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001528 factory()->LookupAsciiSymbol("column_offset"),
1529 foreign_column_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +00001530 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001531 Handle<Foreign> foreign_data =
1532 factory()->NewForeign(&Accessors::ScriptData);
Steve Blocka7e24c12009-10-30 11:49:00 +00001533 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001534 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001535 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001536 factory()->LookupAsciiSymbol("data"),
1537 foreign_data,
Steve Blocka7e24c12009-10-30 11:49:00 +00001538 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001539 Handle<Foreign> foreign_type =
1540 factory()->NewForeign(&Accessors::ScriptType);
Steve Blocka7e24c12009-10-30 11:49:00 +00001541 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001542 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001543 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001544 factory()->LookupAsciiSymbol("type"),
1545 foreign_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00001546 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001547 Handle<Foreign> foreign_compilation_type =
1548 factory()->NewForeign(&Accessors::ScriptCompilationType);
Steve Blocka7e24c12009-10-30 11:49:00 +00001549 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001550 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001551 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001552 factory()->LookupAsciiSymbol("compilation_type"),
1553 foreign_compilation_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00001554 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001555 Handle<Foreign> foreign_line_ends =
1556 factory()->NewForeign(&Accessors::ScriptLineEnds);
Steve Blocka7e24c12009-10-30 11:49:00 +00001557 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001558 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001559 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001560 factory()->LookupAsciiSymbol("line_ends"),
1561 foreign_line_ends,
Steve Blocka7e24c12009-10-30 11:49:00 +00001562 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001563 Handle<Foreign> foreign_context_data =
1564 factory()->NewForeign(&Accessors::ScriptContextData);
Steve Blocka7e24c12009-10-30 11:49:00 +00001565 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001566 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001567 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001568 factory()->LookupAsciiSymbol("context_data"),
1569 foreign_context_data,
Steve Blocka7e24c12009-10-30 11:49:00 +00001570 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001571 Handle<Foreign> foreign_eval_from_script =
1572 factory()->NewForeign(&Accessors::ScriptEvalFromScript);
Steve Blocka7e24c12009-10-30 11:49:00 +00001573 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001574 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001575 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001576 factory()->LookupAsciiSymbol("eval_from_script"),
1577 foreign_eval_from_script,
Steve Blocka7e24c12009-10-30 11:49:00 +00001578 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001579 Handle<Foreign> foreign_eval_from_script_position =
1580 factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001581 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001582 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001583 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001584 factory()->LookupAsciiSymbol("eval_from_script_position"),
1585 foreign_eval_from_script_position,
Steve Blockd0582a62009-12-15 09:54:21 +00001586 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001587 Handle<Foreign> foreign_eval_from_function_name =
1588 factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName);
Steve Blockd0582a62009-12-15 09:54:21 +00001589 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001590 factory()->CopyAppendForeignDescriptor(
Steve Blockd0582a62009-12-15 09:54:21 +00001591 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001592 factory()->LookupAsciiSymbol("eval_from_function_name"),
1593 foreign_eval_from_function_name,
Steve Blocka7e24c12009-10-30 11:49:00 +00001594 common_attributes);
1595
1596 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1597 script_map->set_instance_descriptors(*script_descriptors);
1598
1599 // Allocate the empty script.
Ben Murdoch257744e2011-11-30 15:57:28 +00001600 Handle<Script> script = factory()->NewScript(factory()->empty_string());
Steve Blocka7e24c12009-10-30 11:49:00 +00001601 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
Ben Murdoch257744e2011-11-30 15:57:28 +00001602 heap()->public_set_empty_script(*script);
Steve Blocka7e24c12009-10-30 11:49:00 +00001603 }
Steve Block6ded16b2010-05-10 14:33:55 +01001604 {
1605 // Builtin function for OpaqueReference -- a JSValue-based object,
1606 // that keeps its field isolated from JavaScript code. It may store
1607 // objects, that JavaScript code may not access.
1608 Handle<JSFunction> opaque_reference_fun =
1609 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
Steve Block44f0eee2011-05-26 01:26:41 +01001610 JSValue::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001611 isolate()->initial_object_prototype(),
Steve Block44f0eee2011-05-26 01:26:41 +01001612 Builtins::kIllegal, false);
Steve Block6ded16b2010-05-10 14:33:55 +01001613 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001614 factory()->NewJSObject(isolate()->object_function(), TENURED);
Steve Block6ded16b2010-05-10 14:33:55 +01001615 SetPrototype(opaque_reference_fun, prototype);
1616 global_context()->set_opaque_reference_function(*opaque_reference_fun);
1617 }
1618
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001619 { // --- I n t e r n a l A r r a y ---
1620 // An array constructor on the builtins object that works like
1621 // the public Array constructor, except that its prototype
1622 // doesn't inherit from Object.prototype.
1623 // To be used only for internal work by builtins. Instances
1624 // must not be leaked to user code.
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001625 Handle<JSFunction> array_function =
1626 InstallFunction(builtins,
1627 "InternalArray",
1628 JS_ARRAY_TYPE,
1629 JSArray::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001630 isolate()->initial_object_prototype(),
Ben Murdochc7cc0282012-03-05 14:35:55 +00001631 Builtins::kInternalArrayCode,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001632 true);
1633 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001634 factory()->NewJSObject(isolate()->object_function(), TENURED);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001635 SetPrototype(array_function, prototype);
1636
1637 array_function->shared()->set_construct_stub(
Ben Murdoch257744e2011-11-30 15:57:28 +00001638 isolate()->builtins()->builtin(Builtins::kArrayConstructCode));
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001639 array_function->shared()->DontAdaptArguments();
1640
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001641 // InternalArrays should not use Smi-Only array optimizations. There are too
1642 // many places in the C++ runtime code (e.g. RegEx) that assume that
1643 // elements in InternalArrays can be set to non-Smi values without going
1644 // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
1645 // transition easy to trap. Moreover, they rarely are smi-only.
1646 MaybeObject* maybe_map =
1647 array_function->initial_map()->CopyDropTransitions();
1648 Map* new_map;
1649 if (!maybe_map->To<Map>(&new_map)) return maybe_map;
1650 new_map->set_elements_kind(FAST_ELEMENTS);
1651 array_function->set_initial_map(new_map);
1652
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001653 // Make "length" magic on instances.
1654 Handle<DescriptorArray> array_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001655 factory()->CopyAppendForeignDescriptor(
1656 factory()->empty_descriptor_array(),
1657 factory()->length_symbol(),
1658 factory()->NewForeign(&Accessors::ArrayLength),
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001659 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
1660
1661 array_function->initial_map()->set_instance_descriptors(
1662 *array_descriptors);
Ben Murdochc7cc0282012-03-05 14:35:55 +00001663
1664 global_context()->set_internal_array_function(*array_function);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001665 }
1666
Steve Block6ded16b2010-05-10 14:33:55 +01001667 if (FLAG_disable_native_files) {
1668 PrintF("Warning: Running without installed natives!\n");
1669 return true;
1670 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001671
Andrei Popescu31002712010-02-23 13:46:05 +00001672 // Install natives.
1673 for (int i = Natives::GetDebuggerCount();
1674 i < Natives::GetBuiltinsCount();
1675 i++) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001676 if (!CompileBuiltin(isolate(), i)) return false;
Andrei Popescu402d9372010-02-26 13:31:12 +00001677 // TODO(ager): We really only need to install the JS builtin
1678 // functions on the builtins object after compiling and running
1679 // runtime.js.
1680 if (!InstallJSBuiltins(builtins)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001681 }
1682
1683 InstallNativeFunctions();
1684
Iain Merrick75681382010-08-19 15:07:18 +01001685 // Store the map for the string prototype after the natives has been compiled
Ben Murdochc7cc0282012-03-05 14:35:55 +00001686 // and the String function has been set up.
Iain Merrick75681382010-08-19 15:07:18 +01001687 Handle<JSFunction> string_function(global_context()->string_function());
1688 ASSERT(JSObject::cast(
1689 string_function->initial_map()->prototype())->HasFastProperties());
1690 global_context()->set_string_function_prototype_map(
1691 HeapObject::cast(string_function->initial_map()->prototype())->map());
1692
Steve Blocka7e24c12009-10-30 11:49:00 +00001693 // Install Function.prototype.call and apply.
Ben Murdoch257744e2011-11-30 15:57:28 +00001694 { Handle<String> key = factory()->function_class_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00001695 Handle<JSFunction> function =
Ben Murdoch257744e2011-11-30 15:57:28 +00001696 Handle<JSFunction>::cast(GetProperty(isolate()->global(), key));
Steve Blocka7e24c12009-10-30 11:49:00 +00001697 Handle<JSObject> proto =
1698 Handle<JSObject>(JSObject::cast(function->instance_prototype()));
1699
1700 // Install the call and the apply functions.
1701 Handle<JSFunction> call =
1702 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Steve Block6ded16b2010-05-10 14:33:55 +01001703 Handle<JSObject>::null(),
Steve Block44f0eee2011-05-26 01:26:41 +01001704 Builtins::kFunctionCall,
Steve Blocka7e24c12009-10-30 11:49:00 +00001705 false);
1706 Handle<JSFunction> apply =
1707 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Steve Block6ded16b2010-05-10 14:33:55 +01001708 Handle<JSObject>::null(),
Steve Block44f0eee2011-05-26 01:26:41 +01001709 Builtins::kFunctionApply,
Steve Blocka7e24c12009-10-30 11:49:00 +00001710 false);
1711
1712 // Make sure that Function.prototype.call appears to be compiled.
1713 // The code will never be called, but inline caching for call will
1714 // only work if it appears to be compiled.
1715 call->shared()->DontAdaptArguments();
1716 ASSERT(call->is_compiled());
1717
1718 // Set the expected parameters for apply to 2; required by builtin.
1719 apply->shared()->set_formal_parameter_count(2);
1720
1721 // Set the lengths for the functions to satisfy ECMA-262.
1722 call->shared()->set_length(1);
1723 apply->shared()->set_length(2);
1724 }
1725
Ben Murdoch42effa52011-08-19 16:40:31 +01001726 InstallBuiltinFunctionIds();
1727
Steve Block6ded16b2010-05-10 14:33:55 +01001728 // Create a constructor for RegExp results (a variant of Array that
1729 // predefines the two properties index and match).
1730 {
1731 // RegExpResult initial map.
1732
1733 // Find global.Array.prototype to inherit from.
1734 Handle<JSFunction> array_constructor(global_context()->array_function());
1735 Handle<JSObject> array_prototype(
1736 JSObject::cast(array_constructor->instance_prototype()));
1737
1738 // Add initial map.
1739 Handle<Map> initial_map =
Ben Murdoch257744e2011-11-30 15:57:28 +00001740 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
Steve Block6ded16b2010-05-10 14:33:55 +01001741 initial_map->set_constructor(*array_constructor);
1742
1743 // Set prototype on map.
1744 initial_map->set_non_instance_prototype(false);
1745 initial_map->set_prototype(*array_prototype);
1746
1747 // Update map with length accessor from Array and add "index" and "input".
1748 Handle<Map> array_map(global_context()->js_array_map());
1749 Handle<DescriptorArray> array_descriptors(
1750 array_map->instance_descriptors());
1751 ASSERT_EQ(1, array_descriptors->number_of_descriptors());
1752
1753 Handle<DescriptorArray> reresult_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001754 factory()->NewDescriptorArray(3);
Steve Block6ded16b2010-05-10 14:33:55 +01001755
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001756 DescriptorArray::WhitenessWitness witness(*reresult_descriptors);
1757
1758 reresult_descriptors->CopyFrom(0, *array_descriptors, 0, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001759
1760 int enum_index = 0;
1761 {
Ben Murdoch257744e2011-11-30 15:57:28 +00001762 FieldDescriptor index_field(heap()->index_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001763 JSRegExpResult::kIndexIndex,
1764 NONE,
1765 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001766 reresult_descriptors->Set(1, &index_field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001767 }
1768
1769 {
Ben Murdoch257744e2011-11-30 15:57:28 +00001770 FieldDescriptor input_field(heap()->input_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001771 JSRegExpResult::kInputIndex,
1772 NONE,
1773 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001774 reresult_descriptors->Set(2, &input_field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001775 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001776 reresult_descriptors->Sort(witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001777
1778 initial_map->set_inobject_properties(2);
1779 initial_map->set_pre_allocated_property_fields(2);
1780 initial_map->set_unused_property_fields(0);
1781 initial_map->set_instance_descriptors(*reresult_descriptors);
1782
1783 global_context()->set_regexp_result_map(*initial_map);
1784 }
1785
Steve Blocka7e24c12009-10-30 11:49:00 +00001786#ifdef DEBUG
1787 builtins->Verify();
1788#endif
Andrei Popescu31002712010-02-23 13:46:05 +00001789
Steve Blocka7e24c12009-10-30 11:49:00 +00001790 return true;
1791}
1792
1793
Ben Murdoch257744e2011-11-30 15:57:28 +00001794bool Genesis::InstallExperimentalNatives() {
1795 for (int i = ExperimentalNatives::GetDebuggerCount();
1796 i < ExperimentalNatives::GetBuiltinsCount();
1797 i++) {
1798 if (FLAG_harmony_proxies &&
1799 strcmp(ExperimentalNatives::GetScriptName(i).start(),
1800 "native proxy.js") == 0) {
1801 if (!CompileExperimentalBuiltin(isolate(), i)) return false;
1802 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001803 if (FLAG_harmony_collections &&
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001804 strcmp(ExperimentalNatives::GetScriptName(i).start(),
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001805 "native collection.js") == 0) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001806 if (!CompileExperimentalBuiltin(isolate(), i)) return false;
1807 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001808 }
1809
1810 InstallExperimentalNativeFunctions();
1811
1812 return true;
1813}
1814
1815
Ben Murdochb0fe1622011-05-05 13:52:32 +01001816static Handle<JSObject> ResolveBuiltinIdHolder(
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001817 Handle<Context> global_context,
1818 const char* holder_expr) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001819 Factory* factory = global_context->GetIsolate()->factory();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001820 Handle<GlobalObject> global(global_context->global());
1821 const char* period_pos = strchr(holder_expr, '.');
1822 if (period_pos == NULL) {
1823 return Handle<JSObject>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +01001824 GetProperty(global, factory->LookupAsciiSymbol(holder_expr)));
Steve Block59151502010-09-22 15:07:15 +01001825 }
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001826 ASSERT_EQ(".prototype", period_pos);
1827 Vector<const char> property(holder_expr,
1828 static_cast<int>(period_pos - holder_expr));
1829 Handle<JSFunction> function = Handle<JSFunction>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +01001830 GetProperty(global, factory->LookupSymbol(property)));
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001831 return Handle<JSObject>(JSObject::cast(function->prototype()));
1832}
1833
1834
Ben Murdochb0fe1622011-05-05 13:52:32 +01001835static void InstallBuiltinFunctionId(Handle<JSObject> holder,
1836 const char* function_name,
1837 BuiltinFunctionId id) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001838 Factory* factory = holder->GetIsolate()->factory();
1839 Handle<String> name = factory->LookupAsciiSymbol(function_name);
John Reck59135872010-11-02 12:39:01 -07001840 Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
1841 Handle<JSFunction> function(JSFunction::cast(function_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001842 function->shared()->set_function_data(Smi::FromInt(id));
1843}
1844
1845
Ben Murdochb0fe1622011-05-05 13:52:32 +01001846void Genesis::InstallBuiltinFunctionIds() {
Kristian Monsen25f61362010-05-21 11:50:48 +01001847 HandleScope scope;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001848#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
1849 { \
1850 Handle<JSObject> holder = ResolveBuiltinIdHolder( \
1851 global_context(), #holder_expr); \
1852 BuiltinFunctionId id = k##name; \
1853 InstallBuiltinFunctionId(holder, #fun_name, id); \
Kristian Monsen25f61362010-05-21 11:50:48 +01001854 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001855 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
1856#undef INSTALL_BUILTIN_ID
Kristian Monsen25f61362010-05-21 11:50:48 +01001857}
1858
1859
Steve Block6ded16b2010-05-10 14:33:55 +01001860// Do not forget to update macros.py with named constant
1861// of cache id.
1862#define JSFUNCTION_RESULT_CACHE_LIST(F) \
1863 F(16, global_context()->regexp_function())
1864
1865
Ben Murdoch257744e2011-11-30 15:57:28 +00001866static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
1867 Factory* factory = factory_function->GetIsolate()->factory();
Steve Block6ded16b2010-05-10 14:33:55 +01001868 // Caches are supposed to live for a long time, allocate in old space.
1869 int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
1870 // Cannot use cast as object is not fully initialized yet.
1871 JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
Ben Murdoch257744e2011-11-30 15:57:28 +00001872 *factory->NewFixedArrayWithHoles(array_size, TENURED));
1873 cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function);
Steve Block6ded16b2010-05-10 14:33:55 +01001874 cache->MakeZeroSize();
1875 return cache;
1876}
1877
1878
1879void Genesis::InstallJSFunctionResultCaches() {
1880 const int kNumberOfCaches = 0 +
1881#define F(size, func) + 1
1882 JSFUNCTION_RESULT_CACHE_LIST(F)
1883#undef F
1884 ;
1885
Steve Block44f0eee2011-05-26 01:26:41 +01001886 Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
Steve Block6ded16b2010-05-10 14:33:55 +01001887
1888 int index = 0;
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001889
Ben Murdoch257744e2011-11-30 15:57:28 +00001890#define F(size, func) do { \
1891 FixedArray* cache = CreateCache((size), Handle<JSFunction>(func)); \
1892 caches->set(index++, cache); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001893 } while (false)
1894
1895 JSFUNCTION_RESULT_CACHE_LIST(F);
1896
Steve Block6ded16b2010-05-10 14:33:55 +01001897#undef F
1898
1899 global_context()->set_jsfunction_result_caches(*caches);
1900}
1901
1902
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001903void Genesis::InitializeNormalizedMapCaches() {
1904 Handle<FixedArray> array(
Steve Block44f0eee2011-05-26 01:26:41 +01001905 FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001906 global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
1907}
1908
1909
Andrei Popescu31002712010-02-23 13:46:05 +00001910bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
1911 v8::ExtensionConfiguration* extensions) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001912 Isolate* isolate = global_context->GetIsolate();
Andrei Popescu31002712010-02-23 13:46:05 +00001913 BootstrapperActive active;
Steve Block44f0eee2011-05-26 01:26:41 +01001914 SaveContext saved_context(isolate);
1915 isolate->set_context(*global_context);
Andrei Popescu31002712010-02-23 13:46:05 +00001916 if (!Genesis::InstallExtensions(global_context, extensions)) return false;
1917 Genesis::InstallSpecialObjects(global_context);
1918 return true;
1919}
1920
1921
1922void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
Ben Murdochc7cc0282012-03-05 14:35:55 +00001923 Isolate* isolate = global_context->GetIsolate();
1924 Factory* factory = isolate->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001925 HandleScope scope;
Ben Murdochc7cc0282012-03-05 14:35:55 +00001926 Handle<JSGlobalObject> global(JSGlobalObject::cast(global_context->global()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001927 // Expose the natives in global if a name for it is specified.
1928 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
Ben Murdochc7cc0282012-03-05 14:35:55 +00001929 Handle<String> natives = factory->LookupAsciiSymbol(FLAG_expose_natives_as);
1930 CHECK_NOT_EMPTY_HANDLE(isolate,
1931 JSObject::SetLocalPropertyIgnoreAttributes(
1932 global, natives,
1933 Handle<JSObject>(global->builtins()),
1934 DONT_ENUM));
Steve Blocka7e24c12009-10-30 11:49:00 +00001935 }
1936
Ben Murdochc7cc0282012-03-05 14:35:55 +00001937 Handle<Object> Error = GetProperty(global, "Error");
Steve Blocka7e24c12009-10-30 11:49:00 +00001938 if (Error->IsJSObject()) {
Steve Block44f0eee2011-05-26 01:26:41 +01001939 Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
Ben Murdochc7cc0282012-03-05 14:35:55 +00001940 Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit));
1941 CHECK_NOT_EMPTY_HANDLE(isolate,
1942 JSObject::SetLocalPropertyIgnoreAttributes(
1943 Handle<JSObject>::cast(Error), name,
1944 stack_trace_limit, NONE));
Steve Blocka7e24c12009-10-30 11:49:00 +00001945 }
1946
1947#ifdef ENABLE_DEBUGGER_SUPPORT
1948 // Expose the debug global object in global if a name for it is specified.
1949 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +01001950 Debug* debug = Isolate::Current()->debug();
Steve Blocka7e24c12009-10-30 11:49:00 +00001951 // If loading fails we just bail out without installing the
1952 // debugger but without tanking the whole context.
Steve Block44f0eee2011-05-26 01:26:41 +01001953 if (!debug->Load()) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001954 // Set the security token for the debugger context to the same as
1955 // the shell global context to allow calling between these (otherwise
1956 // exposing debug global object doesn't make much sense).
Steve Block44f0eee2011-05-26 01:26:41 +01001957 debug->debug_context()->set_security_token(
Andrei Popescu31002712010-02-23 13:46:05 +00001958 global_context->security_token());
Steve Blocka7e24c12009-10-30 11:49:00 +00001959
1960 Handle<String> debug_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001961 factory->LookupAsciiSymbol(FLAG_expose_debug_as);
1962 Handle<Object> global_proxy(debug->debug_context()->global_proxy());
Ben Murdochc7cc0282012-03-05 14:35:55 +00001963 CHECK_NOT_EMPTY_HANDLE(isolate,
1964 JSObject::SetLocalPropertyIgnoreAttributes(
1965 global, debug_string, global_proxy, DONT_ENUM));
Steve Blocka7e24c12009-10-30 11:49:00 +00001966 }
1967#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00001968}
1969
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001970static uint32_t Hash(RegisteredExtension* extension) {
1971 return v8::internal::ComputePointerHash(extension);
1972}
1973
1974static bool MatchRegisteredExtensions(void* key1, void* key2) {
1975 return key1 == key2;
1976}
1977
1978Genesis::ExtensionStates::ExtensionStates()
1979 : allocator_(),
1980 map_(MatchRegisteredExtensions, &allocator_, 8)
1981 {}
1982
1983Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
1984 RegisteredExtension* extension) {
1985 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false);
1986 if (entry == NULL) {
1987 return UNVISITED;
1988 }
1989 return static_cast<ExtensionTraversalState>(
1990 reinterpret_cast<intptr_t>(entry->value));
1991}
1992
1993void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
1994 ExtensionTraversalState state) {
1995 map_.Lookup(extension, Hash(extension), true)->value =
1996 reinterpret_cast<void*>(static_cast<intptr_t>(state));
1997}
Steve Blocka7e24c12009-10-30 11:49:00 +00001998
Andrei Popescu31002712010-02-23 13:46:05 +00001999bool Genesis::InstallExtensions(Handle<Context> global_context,
2000 v8::ExtensionConfiguration* extensions) {
Steve Block44f0eee2011-05-26 01:26:41 +01002001 // TODO(isolates): Extensions on multiple isolates may take a little more
2002 // effort. (The external API reads 'ignore'-- does that mean
2003 // we can break the interface?)
2004
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002005
2006 ExtensionStates extension_states; // All extensions have state UNVISITED.
2007 // Install auto extensions.
Steve Blocka7e24c12009-10-30 11:49:00 +00002008 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
2009 while (current != NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002010 if (current->extension()->auto_enable())
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002011 InstallExtension(current, &extension_states);
Steve Blocka7e24c12009-10-30 11:49:00 +00002012 current = current->next();
2013 }
2014
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002015 if (FLAG_expose_gc) InstallExtension("v8/gc", &extension_states);
2016 if (FLAG_expose_externalize_string) {
2017 InstallExtension("v8/externalize", &extension_states);
2018 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002019
2020 if (extensions == NULL) return true;
2021 // Install required extensions
2022 int count = v8::ImplementationUtilities::GetNameCount(extensions);
2023 const char** names = v8::ImplementationUtilities::GetNames(extensions);
2024 for (int i = 0; i < count; i++) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002025 if (!InstallExtension(names[i], &extension_states))
Steve Blocka7e24c12009-10-30 11:49:00 +00002026 return false;
2027 }
2028
2029 return true;
2030}
2031
2032
2033// Installs a named extension. This methods is unoptimized and does
2034// not scale well if we want to support a large number of extensions.
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002035bool Genesis::InstallExtension(const char* name,
2036 ExtensionStates* extension_states) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002037 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
2038 // Loop until we find the relevant extension
2039 while (current != NULL) {
2040 if (strcmp(name, current->extension()->name()) == 0) break;
2041 current = current->next();
2042 }
2043 // Didn't find the extension; fail.
2044 if (current == NULL) {
2045 v8::Utils::ReportApiFailure(
2046 "v8::Context::New()", "Cannot find required extension");
2047 return false;
2048 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002049 return InstallExtension(current, extension_states);
Steve Blocka7e24c12009-10-30 11:49:00 +00002050}
2051
2052
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002053bool Genesis::InstallExtension(v8::RegisteredExtension* current,
2054 ExtensionStates* extension_states) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002055 HandleScope scope;
2056
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002057 if (extension_states->get_state(current) == INSTALLED) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00002058 // The current node has already been visited so there must be a
2059 // cycle in the dependency graph; fail.
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002060 if (extension_states->get_state(current) == VISITED) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002061 v8::Utils::ReportApiFailure(
2062 "v8::Context::New()", "Circular extension dependency");
2063 return false;
2064 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002065 ASSERT(extension_states->get_state(current) == UNVISITED);
2066 extension_states->set_state(current, VISITED);
Steve Blocka7e24c12009-10-30 11:49:00 +00002067 v8::Extension* extension = current->extension();
2068 // Install the extension's dependencies
2069 for (int i = 0; i < extension->dependency_count(); i++) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002070 if (!InstallExtension(extension->dependencies()[i], extension_states))
2071 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002072 }
Steve Block44f0eee2011-05-26 01:26:41 +01002073 Isolate* isolate = Isolate::Current();
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002074 Handle<String> source_code =
2075 isolate->factory()->NewExternalStringFromAscii(extension->source());
2076 bool result = CompileScriptCached(
2077 CStrVector(extension->name()),
2078 source_code,
2079 isolate->bootstrapper()->extensions_cache(),
2080 extension,
2081 Handle<Context>(isolate->context()),
2082 false);
Steve Block44f0eee2011-05-26 01:26:41 +01002083 ASSERT(isolate->has_pending_exception() != result);
Steve Blocka7e24c12009-10-30 11:49:00 +00002084 if (!result) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002085 // We print out the name of the extension that fail to install.
2086 // When an error is thrown during bootstrapping we automatically print
2087 // the line number at which this happened to the console in the isolate
2088 // error throwing functionality.
2089 OS::PrintError("Error installing extension '%s'.\n",
2090 current->extension()->name());
Steve Block44f0eee2011-05-26 01:26:41 +01002091 isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00002092 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002093 extension_states->set_state(current, INSTALLED);
2094 isolate->NotifyExtensionInstalled();
Steve Blocka7e24c12009-10-30 11:49:00 +00002095 return result;
2096}
2097
2098
Andrei Popescu402d9372010-02-26 13:31:12 +00002099bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
2100 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00002101 Factory* factory = builtins->GetIsolate()->factory();
Andrei Popescu402d9372010-02-26 13:31:12 +00002102 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
2103 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
Ben Murdoch257744e2011-11-30 15:57:28 +00002104 Handle<String> name = factory->LookupAsciiSymbol(Builtins::GetName(id));
John Reck59135872010-11-02 12:39:01 -07002105 Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
Andrei Popescu402d9372010-02-26 13:31:12 +00002106 Handle<JSFunction> function
John Reck59135872010-11-02 12:39:01 -07002107 = Handle<JSFunction>(JSFunction::cast(function_object));
Andrei Popescu402d9372010-02-26 13:31:12 +00002108 builtins->set_javascript_builtin(id, *function);
2109 Handle<SharedFunctionInfo> shared
2110 = Handle<SharedFunctionInfo>(function->shared());
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002111 if (!SharedFunctionInfo::EnsureCompiled(shared, CLEAR_EXCEPTION)) {
2112 return false;
2113 }
Iain Merrick75681382010-08-19 15:07:18 +01002114 // Set the code object on the function object.
Ben Murdochb0fe1622011-05-05 13:52:32 +01002115 function->ReplaceCode(function->shared()->code());
Steve Block6ded16b2010-05-10 14:33:55 +01002116 builtins->set_javascript_builtin_code(id, shared->code());
Andrei Popescu402d9372010-02-26 13:31:12 +00002117 }
2118 return true;
Andrei Popescu31002712010-02-23 13:46:05 +00002119}
2120
2121
Steve Blocka7e24c12009-10-30 11:49:00 +00002122bool Genesis::ConfigureGlobalObjects(
2123 v8::Handle<v8::ObjectTemplate> global_proxy_template) {
2124 Handle<JSObject> global_proxy(
2125 JSObject::cast(global_context()->global_proxy()));
Andrei Popescu402d9372010-02-26 13:31:12 +00002126 Handle<JSObject> inner_global(JSObject::cast(global_context()->global()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002127
2128 if (!global_proxy_template.IsEmpty()) {
2129 // Configure the global proxy object.
2130 Handle<ObjectTemplateInfo> proxy_data =
2131 v8::Utils::OpenHandle(*global_proxy_template);
2132 if (!ConfigureApiObject(global_proxy, proxy_data)) return false;
2133
2134 // Configure the inner global object.
2135 Handle<FunctionTemplateInfo> proxy_constructor(
2136 FunctionTemplateInfo::cast(proxy_data->constructor()));
2137 if (!proxy_constructor->prototype_template()->IsUndefined()) {
2138 Handle<ObjectTemplateInfo> inner_data(
2139 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
Andrei Popescu402d9372010-02-26 13:31:12 +00002140 if (!ConfigureApiObject(inner_global, inner_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002141 }
2142 }
2143
Andrei Popescu402d9372010-02-26 13:31:12 +00002144 SetObjectPrototype(global_proxy, inner_global);
Steve Blocka7e24c12009-10-30 11:49:00 +00002145 return true;
2146}
2147
2148
2149bool Genesis::ConfigureApiObject(Handle<JSObject> object,
2150 Handle<ObjectTemplateInfo> object_template) {
2151 ASSERT(!object_template.is_null());
2152 ASSERT(object->IsInstanceOf(
2153 FunctionTemplateInfo::cast(object_template->constructor())));
2154
2155 bool pending_exception = false;
2156 Handle<JSObject> obj =
2157 Execution::InstantiateObject(object_template, &pending_exception);
2158 if (pending_exception) {
Ben Murdoch257744e2011-11-30 15:57:28 +00002159 ASSERT(isolate()->has_pending_exception());
2160 isolate()->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00002161 return false;
2162 }
2163 TransferObject(obj, object);
2164 return true;
2165}
2166
2167
2168void Genesis::TransferNamedProperties(Handle<JSObject> from,
2169 Handle<JSObject> to) {
2170 if (from->HasFastProperties()) {
2171 Handle<DescriptorArray> descs =
2172 Handle<DescriptorArray>(from->map()->instance_descriptors());
2173 for (int i = 0; i < descs->number_of_descriptors(); i++) {
2174 PropertyDetails details = PropertyDetails(descs->GetDetails(i));
2175 switch (details.type()) {
2176 case FIELD: {
2177 HandleScope inner;
2178 Handle<String> key = Handle<String>(descs->GetKey(i));
2179 int index = descs->GetFieldIndex(i);
2180 Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
Ben Murdochc7cc0282012-03-05 14:35:55 +00002181 CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
2182 JSObject::SetLocalPropertyIgnoreAttributes(
2183 to, key, value, details.attributes()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002184 break;
2185 }
2186 case CONSTANT_FUNCTION: {
2187 HandleScope inner;
2188 Handle<String> key = Handle<String>(descs->GetKey(i));
2189 Handle<JSFunction> fun =
2190 Handle<JSFunction>(descs->GetConstantFunction(i));
Ben Murdochc7cc0282012-03-05 14:35:55 +00002191 CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
2192 JSObject::SetLocalPropertyIgnoreAttributes(
2193 to, key, fun, details.attributes()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002194 break;
2195 }
2196 case CALLBACKS: {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002197 LookupResult result(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00002198 to->LocalLookup(descs->GetKey(i), &result);
2199 // If the property is already there we skip it
Andrei Popescu402d9372010-02-26 13:31:12 +00002200 if (result.IsProperty()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00002201 HandleScope inner;
Andrei Popescu31002712010-02-23 13:46:05 +00002202 ASSERT(!to->HasFastProperties());
2203 // Add to dictionary.
Steve Blocka7e24c12009-10-30 11:49:00 +00002204 Handle<String> key = Handle<String>(descs->GetKey(i));
Andrei Popescu31002712010-02-23 13:46:05 +00002205 Handle<Object> callbacks(descs->GetCallbacksObject(i));
2206 PropertyDetails d =
2207 PropertyDetails(details.attributes(), CALLBACKS, details.index());
Ben Murdochc7cc0282012-03-05 14:35:55 +00002208 JSObject::SetNormalizedProperty(to, key, callbacks, d);
Steve Blocka7e24c12009-10-30 11:49:00 +00002209 break;
2210 }
2211 case MAP_TRANSITION:
Ben Murdoch589d6972011-11-30 16:04:58 +00002212 case ELEMENTS_TRANSITION:
Steve Blocka7e24c12009-10-30 11:49:00 +00002213 case CONSTANT_TRANSITION:
2214 case NULL_DESCRIPTOR:
2215 // Ignore non-properties.
2216 break;
2217 case NORMAL:
2218 // Do not occur since the from object has fast properties.
Ben Murdoch257744e2011-11-30 15:57:28 +00002219 case HANDLER:
Steve Blocka7e24c12009-10-30 11:49:00 +00002220 case INTERCEPTOR:
Ben Murdoch257744e2011-11-30 15:57:28 +00002221 // No element in instance descriptors have proxy or interceptor type.
Steve Blocka7e24c12009-10-30 11:49:00 +00002222 UNREACHABLE();
2223 break;
2224 }
2225 }
2226 } else {
2227 Handle<StringDictionary> properties =
2228 Handle<StringDictionary>(from->property_dictionary());
2229 int capacity = properties->Capacity();
2230 for (int i = 0; i < capacity; i++) {
2231 Object* raw_key(properties->KeyAt(i));
2232 if (properties->IsKey(raw_key)) {
2233 ASSERT(raw_key->IsString());
2234 // If the property is already there we skip it.
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002235 LookupResult result(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00002236 to->LocalLookup(String::cast(raw_key), &result);
Andrei Popescu402d9372010-02-26 13:31:12 +00002237 if (result.IsProperty()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00002238 // Set the property.
2239 Handle<String> key = Handle<String>(String::cast(raw_key));
2240 Handle<Object> value = Handle<Object>(properties->ValueAt(i));
2241 if (value->IsJSGlobalPropertyCell()) {
2242 value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
2243 }
2244 PropertyDetails details = properties->DetailsAt(i);
Ben Murdochc7cc0282012-03-05 14:35:55 +00002245 CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
2246 JSObject::SetLocalPropertyIgnoreAttributes(
2247 to, key, value, details.attributes()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002248 }
2249 }
2250 }
2251}
2252
2253
2254void Genesis::TransferIndexedProperties(Handle<JSObject> from,
2255 Handle<JSObject> to) {
2256 // Cloning the elements array is sufficient.
2257 Handle<FixedArray> from_elements =
2258 Handle<FixedArray>(FixedArray::cast(from->elements()));
Steve Block44f0eee2011-05-26 01:26:41 +01002259 Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00002260 to->set_elements(*to_elements);
2261}
2262
2263
2264void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
2265 HandleScope outer;
Ben Murdoch257744e2011-11-30 15:57:28 +00002266 Factory* factory = from->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00002267
2268 ASSERT(!from->IsJSArray());
2269 ASSERT(!to->IsJSArray());
2270
2271 TransferNamedProperties(from, to);
2272 TransferIndexedProperties(from, to);
2273
2274 // Transfer the prototype (new map is needed).
2275 Handle<Map> old_to_map = Handle<Map>(to->map());
Ben Murdoch257744e2011-11-30 15:57:28 +00002276 Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002277 new_to_map->set_prototype(from->map()->prototype());
2278 to->set_map(*new_to_map);
2279}
2280
2281
2282void Genesis::MakeFunctionInstancePrototypeWritable() {
Steve Block44f0eee2011-05-26 01:26:41 +01002283 // The maps with writable prototype are created in CreateEmptyFunction
2284 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
2285 // created with read-only prototype for JS builtins processing.
2286 ASSERT(!function_instance_map_writable_prototype_.is_null());
2287 ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00002288
Steve Block44f0eee2011-05-26 01:26:41 +01002289 // Replace function instance maps to make prototype writable.
2290 global_context()->set_function_map(
2291 *function_instance_map_writable_prototype_);
2292 global_context()->set_strict_mode_function_map(
2293 *strict_mode_function_instance_map_writable_prototype_);
Steve Blocka7e24c12009-10-30 11:49:00 +00002294}
2295
2296
Ben Murdoch257744e2011-11-30 15:57:28 +00002297Genesis::Genesis(Isolate* isolate,
2298 Handle<Object> global_object,
Steve Blocka7e24c12009-10-30 11:49:00 +00002299 v8::Handle<v8::ObjectTemplate> global_template,
Ben Murdoch257744e2011-11-30 15:57:28 +00002300 v8::ExtensionConfiguration* extensions) : isolate_(isolate) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002301 result_ = Handle<Context>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +00002302 // If V8 isn't running and cannot be initialized, just return.
2303 if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
2304
2305 // Before creating the roots we must save the context and restore it
2306 // on all function exits.
2307 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01002308 SaveContext saved_context(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002309
Andrei Popescu31002712010-02-23 13:46:05 +00002310 Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
2311 if (!new_context.is_null()) {
2312 global_context_ =
Steve Block44f0eee2011-05-26 01:26:41 +01002313 Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
Ben Murdochb0fe1622011-05-05 13:52:32 +01002314 AddToWeakGlobalContextList(*global_context_);
Steve Block44f0eee2011-05-26 01:26:41 +01002315 isolate->set_context(*global_context_);
2316 isolate->counters()->contexts_created_by_snapshot()->Increment();
Andrei Popescu402d9372010-02-26 13:31:12 +00002317 Handle<GlobalObject> inner_global;
Andrei Popescu31002712010-02-23 13:46:05 +00002318 Handle<JSGlobalProxy> global_proxy =
2319 CreateNewGlobals(global_template,
2320 global_object,
Andrei Popescu402d9372010-02-26 13:31:12 +00002321 &inner_global);
2322
Andrei Popescu31002712010-02-23 13:46:05 +00002323 HookUpGlobalProxy(inner_global, global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +00002324 HookUpInnerGlobal(inner_global);
2325
Andrei Popescu31002712010-02-23 13:46:05 +00002326 if (!ConfigureGlobalObjects(global_template)) return;
2327 } else {
2328 // We get here if there was no context snapshot.
2329 CreateRoots();
Ben Murdoch257744e2011-11-30 15:57:28 +00002330 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002331 CreateStrictModeFunctionMaps(empty_function);
Andrei Popescu31002712010-02-23 13:46:05 +00002332 Handle<GlobalObject> inner_global;
2333 Handle<JSGlobalProxy> global_proxy =
2334 CreateNewGlobals(global_template, global_object, &inner_global);
2335 HookUpGlobalProxy(inner_global, global_proxy);
2336 InitializeGlobal(inner_global, empty_function);
Steve Block6ded16b2010-05-10 14:33:55 +01002337 InstallJSFunctionResultCaches();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002338 InitializeNormalizedMapCaches();
Kristian Monsen25f61362010-05-21 11:50:48 +01002339 if (!InstallNatives()) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002340
Andrei Popescu31002712010-02-23 13:46:05 +00002341 MakeFunctionInstancePrototypeWritable();
Steve Blocka7e24c12009-10-30 11:49:00 +00002342
Andrei Popescu31002712010-02-23 13:46:05 +00002343 if (!ConfigureGlobalObjects(global_template)) return;
Steve Block44f0eee2011-05-26 01:26:41 +01002344 isolate->counters()->contexts_created_from_scratch()->Increment();
Andrei Popescu31002712010-02-23 13:46:05 +00002345 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002346
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002347 // Initialize experimental globals and install experimental natives.
2348 InitializeExperimentalGlobal();
Ben Murdoch257744e2011-11-30 15:57:28 +00002349 if (!InstallExperimentalNatives()) return;
2350
Steve Blocka7e24c12009-10-30 11:49:00 +00002351 result_ = global_context_;
2352}
2353
2354
2355// Support for thread preemption.
2356
2357// Reserve space for statics needing saving and restoring.
2358int Bootstrapper::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01002359 return sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002360}
2361
2362
2363// Archive statics that are thread local.
2364char* Bootstrapper::ArchiveState(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +01002365 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
2366 nesting_ = 0;
2367 return to + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002368}
2369
2370
2371// Restore statics that are thread local.
2372char* Bootstrapper::RestoreState(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +01002373 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
2374 return from + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002375}
2376
2377
2378// Called when the top-level V8 mutex is destroyed.
2379void Bootstrapper::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01002380 ASSERT(!IsActive());
Steve Blocka7e24c12009-10-30 11:49:00 +00002381}
2382
2383} } // namespace v8::internal