OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 cache_->set(length + 1, *shared); | 84 cache_->set(length + 1, *shared); |
85 Script::cast(shared->script())->set_type(Smi::FromInt(type_)); | 85 Script::cast(shared->script())->set_type(Smi::FromInt(type_)); |
86 } | 86 } |
87 | 87 |
88 private: | 88 private: |
89 Script::Type type_; | 89 Script::Type type_; |
90 FixedArray* cache_; | 90 FixedArray* cache_; |
91 DISALLOW_COPY_AND_ASSIGN(SourceCodeCache); | 91 DISALLOW_COPY_AND_ASSIGN(SourceCodeCache); |
92 }; | 92 }; |
93 | 93 |
94 static SourceCodeCache natives_cache(Script::TYPE_NATIVE); | |
95 static SourceCodeCache extensions_cache(Script::TYPE_EXTENSION); | 94 static SourceCodeCache extensions_cache(Script::TYPE_EXTENSION); |
96 // This is for delete, not delete[]. | 95 // This is for delete, not delete[]. |
97 static List<char*>* delete_these_non_arrays_on_tear_down = NULL; | 96 static List<char*>* delete_these_non_arrays_on_tear_down = NULL; |
98 // This is for delete[] | 97 // This is for delete[] |
99 static List<char*>* delete_these_arrays_on_tear_down = NULL; | 98 static List<char*>* delete_these_arrays_on_tear_down = NULL; |
100 | 99 |
101 | 100 |
102 NativesExternalStringResource::NativesExternalStringResource(const char* source) | 101 NativesExternalStringResource::NativesExternalStringResource(const char* source) |
103 : data_(source), length_(StrLength(source)) { | 102 : data_(source), length_(StrLength(source)) { |
104 if (delete_these_non_arrays_on_tear_down == NULL) { | 103 if (delete_these_non_arrays_on_tear_down == NULL) { |
(...skipping 22 matching lines...) Expand all Loading... |
127 Handle<String> source_code = | 126 Handle<String> source_code = |
128 Factory::NewStringFromAscii(Natives::GetScriptSource(index)); | 127 Factory::NewStringFromAscii(Natives::GetScriptSource(index)); |
129 Heap::natives_source_cache()->set(index, *source_code); | 128 Heap::natives_source_cache()->set(index, *source_code); |
130 } | 129 } |
131 } | 130 } |
132 Handle<Object> cached_source(Heap::natives_source_cache()->get(index)); | 131 Handle<Object> cached_source(Heap::natives_source_cache()->get(index)); |
133 return Handle<String>::cast(cached_source); | 132 return Handle<String>::cast(cached_source); |
134 } | 133 } |
135 | 134 |
136 | 135 |
137 bool Bootstrapper::NativesCacheLookup(Vector<const char> name, | |
138 Handle<SharedFunctionInfo>* handle) { | |
139 return natives_cache.Lookup(name, handle); | |
140 } | |
141 | |
142 | |
143 void Bootstrapper::NativesCacheAdd(Vector<const char> name, | |
144 Handle<SharedFunctionInfo> fun) { | |
145 natives_cache.Add(name, fun); | |
146 } | |
147 | |
148 | |
149 void Bootstrapper::Initialize(bool create_heap_objects) { | 136 void Bootstrapper::Initialize(bool create_heap_objects) { |
150 natives_cache.Initialize(create_heap_objects); | |
151 extensions_cache.Initialize(create_heap_objects); | 137 extensions_cache.Initialize(create_heap_objects); |
152 } | 138 } |
153 | 139 |
154 | 140 |
155 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { | 141 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { |
156 char* memory = new char[bytes]; | 142 char* memory = new char[bytes]; |
157 if (memory != NULL) { | 143 if (memory != NULL) { |
158 if (delete_these_arrays_on_tear_down == NULL) { | 144 if (delete_these_arrays_on_tear_down == NULL) { |
159 delete_these_arrays_on_tear_down = new List<char*>(2); | 145 delete_these_arrays_on_tear_down = new List<char*>(2); |
160 } | 146 } |
(...skipping 19 matching lines...) Expand all Loading... |
180 int len = delete_these_arrays_on_tear_down->length(); | 166 int len = delete_these_arrays_on_tear_down->length(); |
181 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations. | 167 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations. |
182 for (int i = 0; i < len; i++) { | 168 for (int i = 0; i < len; i++) { |
183 delete[] delete_these_arrays_on_tear_down->at(i); | 169 delete[] delete_these_arrays_on_tear_down->at(i); |
184 delete_these_arrays_on_tear_down->at(i) = NULL; | 170 delete_these_arrays_on_tear_down->at(i) = NULL; |
185 } | 171 } |
186 delete delete_these_arrays_on_tear_down; | 172 delete delete_these_arrays_on_tear_down; |
187 delete_these_arrays_on_tear_down = NULL; | 173 delete_these_arrays_on_tear_down = NULL; |
188 } | 174 } |
189 | 175 |
190 natives_cache.Initialize(false); // Yes, symmetrical | 176 extensions_cache.Initialize(false); // Yes, symmetrical |
191 extensions_cache.Initialize(false); | |
192 } | 177 } |
193 | 178 |
194 | 179 |
195 class Genesis BASE_EMBEDDED { | 180 class Genesis BASE_EMBEDDED { |
196 public: | 181 public: |
197 Genesis(Handle<Object> global_object, | 182 Genesis(Handle<Object> global_object, |
198 v8::Handle<v8::ObjectTemplate> global_template, | 183 v8::Handle<v8::ObjectTemplate> global_template, |
199 v8::ExtensionConfiguration* extensions); | 184 v8::ExtensionConfiguration* extensions); |
200 ~Genesis(); | 185 ~Genesis() { } |
201 | 186 |
202 Handle<Context> result() { return result_; } | 187 Handle<Context> result() { return result_; } |
203 | 188 |
204 Genesis* previous() { return previous_; } | 189 Genesis* previous() { return previous_; } |
205 static Genesis* current() { return current_; } | |
206 | |
207 // Support for thread preemption. | |
208 static int ArchiveSpacePerThread(); | |
209 static char* ArchiveState(char* to); | |
210 static char* RestoreState(char* from); | |
211 | 190 |
212 private: | 191 private: |
213 Handle<Context> global_context_; | 192 Handle<Context> global_context_; |
214 | 193 |
215 // There may be more than one active genesis object: When GC is | 194 // There may be more than one active genesis object: When GC is |
216 // triggered during environment creation there may be weak handle | 195 // triggered during environment creation there may be weak handle |
217 // processing callbacks which may create new environments. | 196 // processing callbacks which may create new environments. |
218 Genesis* previous_; | 197 Genesis* previous_; |
219 static Genesis* current_; | |
220 | 198 |
221 Handle<Context> global_context() { return global_context_; } | 199 Handle<Context> global_context() { return global_context_; } |
222 | 200 |
223 void CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, | 201 // Creates some basic objects. Used for creating a context from scratch. |
224 Handle<Object> global_object); | 202 void CreateRoots(); |
| 203 // Creates the empty function. Used for creating a context from scratch. |
| 204 Handle<JSFunction> CreateEmptyFunction(); |
| 205 // Creates the global objects using the global and the template passed in |
| 206 // through the API. We call this regardless of whether we are building a |
| 207 // context from scratch or using a deserialized one from the partial snapshot |
| 208 // but in the latter case we don't use the objects it produces directly, as |
| 209 // we have to used the deserialized ones that are linked together with the |
| 210 // rest of the context snapshot. |
| 211 Handle<JSGlobalProxy> CreateNewGlobals( |
| 212 v8::Handle<v8::ObjectTemplate> global_template, |
| 213 Handle<Object> global_object, |
| 214 Handle<GlobalObject>* global_proxy_out); |
| 215 // Hooks the given global proxy into the context. If the context was created |
| 216 // by deserialization then this will unhook the global proxy that was |
| 217 // deserialized, leaving the GC to pick it up. |
| 218 void HookUpGlobalProxy(Handle<GlobalObject> inner_global, |
| 219 Handle<JSGlobalProxy> global_proxy); |
| 220 // Similarly, we want to use the inner global that has been created by the |
| 221 // templates passed through the API. The inner global from the snapshot is |
| 222 // detached from the other objects in the snapshot. |
| 223 void HookUpInnerGlobal(Handle<GlobalObject> inner_global); |
| 224 // New context initialization. Used for creating a context from scratch. |
| 225 void InitializeGlobal(Handle<GlobalObject> inner_global, |
| 226 Handle<JSFunction> empty_function); |
| 227 // Installs the contents of the native .js files on the global objects. |
| 228 // Used for creating a context from scratch. |
225 void InstallNativeFunctions(); | 229 void InstallNativeFunctions(); |
226 bool InstallNatives(); | 230 bool InstallNatives(); |
227 bool InstallExtensions(v8::ExtensionConfiguration* extensions); | 231 // Used both for deserialized and from-scratch contexts to add the extensions |
228 bool InstallExtension(const char* name); | 232 // provided. |
229 bool InstallExtension(v8::RegisteredExtension* current); | 233 static bool InstallExtensions(Handle<Context> global_context, |
230 bool InstallSpecialObjects(); | 234 v8::ExtensionConfiguration* extensions); |
| 235 static bool InstallExtension(const char* name); |
| 236 static bool InstallExtension(v8::RegisteredExtension* current); |
| 237 static void InstallSpecialObjects(Handle<Context> global_context); |
231 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); | 238 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); |
232 bool ConfigureApiObject(Handle<JSObject> object, | 239 bool ConfigureApiObject(Handle<JSObject> object, |
233 Handle<ObjectTemplateInfo> object_template); | 240 Handle<ObjectTemplateInfo> object_template); |
234 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); | 241 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); |
235 | 242 |
236 // Migrates all properties from the 'from' object to the 'to' | 243 // Migrates all properties from the 'from' object to the 'to' |
237 // object and overrides the prototype in 'to' with the one from | 244 // object and overrides the prototype in 'to' with the one from |
238 // 'from'. | 245 // 'from'. |
239 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 246 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
240 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); | 247 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
241 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); | 248 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); |
242 | 249 |
243 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( | 250 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( |
244 bool make_prototype_read_only, | 251 bool make_prototype_read_only, |
245 bool make_prototype_enumerable = false); | 252 bool make_prototype_enumerable = false); |
246 void MakeFunctionInstancePrototypeWritable(); | 253 void MakeFunctionInstancePrototypeWritable(); |
247 | 254 |
248 static bool CompileBuiltin(int index); | 255 static bool CompileBuiltin(int index); |
249 static bool CompileNative(Vector<const char> name, Handle<String> source); | 256 static bool CompileNative(Vector<const char> name, Handle<String> source); |
250 static bool CompileScriptCached(Vector<const char> name, | 257 static bool CompileScriptCached(Vector<const char> name, |
251 Handle<String> source, | 258 Handle<String> source, |
252 SourceCodeCache* cache, | 259 SourceCodeCache* cache, |
253 v8::Extension* extension, | 260 v8::Extension* extension, |
| 261 Handle<Context> top_context, |
254 bool use_runtime_context); | 262 bool use_runtime_context); |
255 | 263 |
256 Handle<Context> result_; | 264 Handle<Context> result_; |
| 265 Handle<JSFunction> empty_function_; |
| 266 BootstrapperActive active_; |
| 267 friend class Bootstrapper; |
257 }; | 268 }; |
258 | 269 |
259 Genesis* Genesis::current_ = NULL; | |
260 | |
261 | 270 |
262 void Bootstrapper::Iterate(ObjectVisitor* v) { | 271 void Bootstrapper::Iterate(ObjectVisitor* v) { |
263 natives_cache.Iterate(v); | |
264 v->Synchronize("NativesCache"); | |
265 extensions_cache.Iterate(v); | 272 extensions_cache.Iterate(v); |
266 v->Synchronize("Extensions"); | 273 v->Synchronize("Extensions"); |
267 } | 274 } |
268 | 275 |
269 | 276 |
270 bool Bootstrapper::IsActive() { | |
271 return Genesis::current() != NULL; | |
272 } | |
273 | |
274 | |
275 Handle<Context> Bootstrapper::CreateEnvironment( | 277 Handle<Context> Bootstrapper::CreateEnvironment( |
276 Handle<Object> global_object, | 278 Handle<Object> global_object, |
277 v8::Handle<v8::ObjectTemplate> global_template, | 279 v8::Handle<v8::ObjectTemplate> global_template, |
278 v8::ExtensionConfiguration* extensions) { | 280 v8::ExtensionConfiguration* extensions) { |
| 281 HandleScope scope; |
| 282 Handle<Context> env; |
279 Genesis genesis(global_object, global_template, extensions); | 283 Genesis genesis(global_object, global_template, extensions); |
280 return genesis.result(); | 284 env = genesis.result(); |
| 285 if (!env.is_null()) { |
| 286 if (InstallExtensions(env, extensions)) { |
| 287 return env; |
| 288 } |
| 289 } |
| 290 return Handle<Context>(); |
281 } | 291 } |
282 | 292 |
283 | 293 |
284 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) { | 294 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) { |
285 // object.__proto__ = proto; | 295 // object.__proto__ = proto; |
286 Handle<Map> old_to_map = Handle<Map>(object->map()); | 296 Handle<Map> old_to_map = Handle<Map>(object->map()); |
287 Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map); | 297 Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map); |
288 new_to_map->set_prototype(*proto); | 298 new_to_map->set_prototype(*proto); |
289 object->set_map(*new_to_map); | 299 object->set_map(*new_to_map); |
290 } | 300 } |
291 | 301 |
292 | 302 |
293 void Bootstrapper::DetachGlobal(Handle<Context> env) { | 303 void Bootstrapper::DetachGlobal(Handle<Context> env) { |
294 JSGlobalProxy::cast(env->global_proxy())->set_context(*Factory::null_value()); | 304 JSGlobalProxy::cast(env->global_proxy())->set_context(*Factory::null_value()); |
295 SetObjectPrototype(Handle<JSObject>(env->global_proxy()), | 305 SetObjectPrototype(Handle<JSObject>(env->global_proxy()), |
296 Factory::null_value()); | 306 Factory::null_value()); |
297 env->set_global_proxy(env->global()); | 307 env->set_global_proxy(env->global()); |
298 env->global()->set_global_receiver(env->global()); | 308 env->global()->set_global_receiver(env->global()); |
299 } | 309 } |
300 | 310 |
301 | 311 |
302 Genesis::~Genesis() { | |
303 ASSERT(current_ == this); | |
304 current_ = previous_; | |
305 } | |
306 | |
307 | |
308 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, | 312 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, |
309 const char* name, | 313 const char* name, |
310 InstanceType type, | 314 InstanceType type, |
311 int instance_size, | 315 int instance_size, |
312 Handle<JSObject> prototype, | 316 Handle<JSObject> prototype, |
313 Builtins::Name call, | 317 Builtins::Name call, |
314 bool is_ecma_native) { | 318 bool is_ecma_native) { |
315 Handle<String> symbol = Factory::LookupAsciiSymbol(name); | 319 Handle<String> symbol = Factory::LookupAsciiSymbol(name); |
316 Handle<Code> call_code = Handle<Code>(Builtins::builtin(call)); | 320 Handle<Code> call_code = Handle<Code>(Builtins::builtin(call)); |
317 Handle<JSFunction> function = | 321 Handle<JSFunction> function = |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 Factory::CopyAppendProxyDescriptor( | 381 Factory::CopyAppendProxyDescriptor( |
378 result, | 382 result, |
379 Factory::caller_symbol(), | 383 Factory::caller_symbol(), |
380 Factory::NewProxy(&Accessors::FunctionCaller), | 384 Factory::NewProxy(&Accessors::FunctionCaller), |
381 attributes); | 385 attributes); |
382 | 386 |
383 return result; | 387 return result; |
384 } | 388 } |
385 | 389 |
386 | 390 |
387 void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, | 391 Handle<JSFunction> Genesis::CreateEmptyFunction() { |
388 Handle<Object> global_object) { | |
389 HandleScope scope; | |
390 // Allocate the global context FixedArray first and then patch the | |
391 // closure and extension object later (we need the empty function | |
392 // and the global object, but in order to create those, we need the | |
393 // global context). | |
394 global_context_ = | |
395 Handle<Context>::cast( | |
396 GlobalHandles::Create(*Factory::NewGlobalContext())); | |
397 Top::set_context(*global_context()); | |
398 | |
399 // Allocate the message listeners object. | |
400 v8::NeanderArray listeners; | |
401 global_context()->set_message_listeners(*listeners.value()); | |
402 | |
403 // Allocate the map for function instances. | 392 // Allocate the map for function instances. |
404 Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 393 Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
405 global_context()->set_function_instance_map(*fm); | 394 global_context()->set_function_instance_map(*fm); |
406 // Please note that the prototype property for function instances must be | 395 // Please note that the prototype property for function instances must be |
407 // writable. | 396 // writable. |
408 Handle<DescriptorArray> function_map_descriptors = | 397 Handle<DescriptorArray> function_map_descriptors = |
409 ComputeFunctionInstanceDescriptor(false, false); | 398 ComputeFunctionInstanceDescriptor(false, false); |
410 fm->set_instance_descriptors(*function_map_descriptors); | 399 fm->set_instance_descriptors(*function_map_descriptors); |
411 | 400 |
412 // Allocate the function map first and then patch the prototype later | 401 // Allocate the function map first and then patch the prototype later |
(...skipping 23 matching lines...) Expand all Loading... |
436 object_function_map-> | 425 object_function_map-> |
437 set_instance_descriptors(Heap::empty_descriptor_array()); | 426 set_instance_descriptors(Heap::empty_descriptor_array()); |
438 } | 427 } |
439 | 428 |
440 // Allocate the empty function as the prototype for function ECMAScript | 429 // Allocate the empty function as the prototype for function ECMAScript |
441 // 262 15.3.4. | 430 // 262 15.3.4. |
442 Handle<String> symbol = Factory::LookupAsciiSymbol("Empty"); | 431 Handle<String> symbol = Factory::LookupAsciiSymbol("Empty"); |
443 Handle<JSFunction> empty_function = | 432 Handle<JSFunction> empty_function = |
444 Factory::NewFunction(symbol, Factory::null_value()); | 433 Factory::NewFunction(symbol, Factory::null_value()); |
445 | 434 |
446 { // --- E m p t y --- | 435 // --- E m p t y --- |
447 Handle<Code> code = | 436 Handle<Code> code = |
448 Handle<Code>(Builtins::builtin(Builtins::EmptyFunction)); | 437 Handle<Code>(Builtins::builtin(Builtins::EmptyFunction)); |
449 empty_function->set_code(*code); | 438 empty_function->set_code(*code); |
450 Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}")); | 439 Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}")); |
451 Handle<Script> script = Factory::NewScript(source); | 440 Handle<Script> script = Factory::NewScript(source); |
452 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 441 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
453 empty_function->shared()->set_script(*script); | 442 empty_function->shared()->set_script(*script); |
454 empty_function->shared()->set_start_position(0); | 443 empty_function->shared()->set_start_position(0); |
455 empty_function->shared()->set_end_position(source->length()); | 444 empty_function->shared()->set_end_position(source->length()); |
456 empty_function->shared()->DontAdaptArguments(); | 445 empty_function->shared()->DontAdaptArguments(); |
457 global_context()->function_map()->set_prototype(*empty_function); | 446 global_context()->function_map()->set_prototype(*empty_function); |
458 global_context()->function_instance_map()->set_prototype(*empty_function); | 447 global_context()->function_instance_map()->set_prototype(*empty_function); |
459 | 448 |
460 // Allocate the function map first and then patch the prototype later | 449 // Allocate the function map first and then patch the prototype later |
461 Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(fm); | 450 Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(fm); |
462 empty_fm->set_instance_descriptors(*function_map_descriptors); | 451 empty_fm->set_instance_descriptors(*function_map_descriptors); |
463 empty_fm->set_prototype(global_context()->object_function()->prototype()); | 452 empty_fm->set_prototype(global_context()->object_function()->prototype()); |
464 empty_function->set_map(*empty_fm); | 453 empty_function->set_map(*empty_fm); |
| 454 return empty_function; |
| 455 } |
| 456 |
| 457 |
| 458 void Genesis::CreateRoots() { |
| 459 // Allocate the global context FixedArray first and then patch the |
| 460 // closure and extension object later (we need the empty function |
| 461 // and the global object, but in order to create those, we need the |
| 462 // global context). |
| 463 global_context_ = |
| 464 Handle<Context>::cast( |
| 465 GlobalHandles::Create(*Factory::NewGlobalContext())); |
| 466 Top::set_context(*global_context()); |
| 467 |
| 468 // Allocate the message listeners object. |
| 469 { |
| 470 v8::NeanderArray listeners; |
| 471 global_context()->set_message_listeners(*listeners.value()); |
| 472 } |
| 473 } |
| 474 |
| 475 |
| 476 Handle<JSGlobalProxy> Genesis::CreateNewGlobals( |
| 477 v8::Handle<v8::ObjectTemplate> global_template, |
| 478 Handle<Object> global_object, |
| 479 Handle<GlobalObject>* inner_global_out) { |
| 480 // The argument global_template aka data is an ObjectTemplateInfo. |
| 481 // It has a constructor pointer that points at global_constructor which is a |
| 482 // FunctionTemplateInfo. |
| 483 // The global_constructor is used to create or reinitialize the global_proxy. |
| 484 // The global_constructor also has a prototype_template pointer that points at |
| 485 // js_global_template which is an ObjectTemplateInfo. |
| 486 // That in turn has a constructor pointer that points at |
| 487 // js_global_constructor which is a FunctionTemplateInfo. |
| 488 // js_global_constructor is used to make js_global_function |
| 489 // js_global_function is used to make the new inner_global. |
| 490 // |
| 491 // --- G l o b a l --- |
| 492 // Step 1: Create a fresh inner JSGlobalObject. |
| 493 Handle<JSFunction> js_global_function; |
| 494 Handle<ObjectTemplateInfo> js_global_template; |
| 495 if (!global_template.IsEmpty()) { |
| 496 // Get prototype template of the global_template. |
| 497 Handle<ObjectTemplateInfo> data = |
| 498 v8::Utils::OpenHandle(*global_template); |
| 499 Handle<FunctionTemplateInfo> global_constructor = |
| 500 Handle<FunctionTemplateInfo>( |
| 501 FunctionTemplateInfo::cast(data->constructor())); |
| 502 Handle<Object> proto_template(global_constructor->prototype_template()); |
| 503 if (!proto_template->IsUndefined()) { |
| 504 js_global_template = |
| 505 Handle<ObjectTemplateInfo>::cast(proto_template); |
| 506 } |
465 } | 507 } |
466 | 508 |
467 { // --- G l o b a l --- | 509 if (js_global_template.is_null()) { |
468 // Step 1: create a fresh inner JSGlobalObject | 510 Handle<String> name = Handle<String>(Heap::empty_symbol()); |
469 Handle<GlobalObject> object; | 511 Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal)); |
470 { | 512 js_global_function = |
471 Handle<JSFunction> js_global_function; | 513 Factory::NewFunction(name, JS_GLOBAL_OBJECT_TYPE, |
472 Handle<ObjectTemplateInfo> js_global_template; | 514 JSGlobalObject::kSize, code, true); |
473 if (!global_template.IsEmpty()) { | 515 // Change the constructor property of the prototype of the |
474 // Get prototype template of the global_template | 516 // hidden global function to refer to the Object function. |
475 Handle<ObjectTemplateInfo> data = | 517 Handle<JSObject> prototype = |
476 v8::Utils::OpenHandle(*global_template); | 518 Handle<JSObject>( |
477 Handle<FunctionTemplateInfo> global_constructor = | 519 JSObject::cast(js_global_function->instance_prototype())); |
478 Handle<FunctionTemplateInfo>( | 520 SetProperty(prototype, Factory::constructor_symbol(), |
479 FunctionTemplateInfo::cast(data->constructor())); | 521 Top::object_function(), NONE); |
480 Handle<Object> proto_template(global_constructor->prototype_template()); | 522 } else { |
481 if (!proto_template->IsUndefined()) { | 523 Handle<FunctionTemplateInfo> js_global_constructor( |
482 js_global_template = | 524 FunctionTemplateInfo::cast(js_global_template->constructor())); |
483 Handle<ObjectTemplateInfo>::cast(proto_template); | 525 js_global_function = |
484 } | 526 Factory::CreateApiFunction(js_global_constructor, |
485 } | 527 Factory::InnerGlobalObject); |
| 528 } |
486 | 529 |
487 if (js_global_template.is_null()) { | 530 js_global_function->initial_map()->set_is_hidden_prototype(); |
488 Handle<String> name = Handle<String>(Heap::empty_symbol()); | 531 Handle<GlobalObject> inner_global = |
489 Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal)); | 532 Factory::NewGlobalObject(js_global_function); |
490 js_global_function = | 533 if (inner_global_out != NULL) { |
491 Factory::NewFunction(name, JS_GLOBAL_OBJECT_TYPE, | 534 *inner_global_out = inner_global; |
492 JSGlobalObject::kSize, code, true); | 535 } |
493 // Change the constructor property of the prototype of the | |
494 // hidden global function to refer to the Object function. | |
495 Handle<JSObject> prototype = | |
496 Handle<JSObject>( | |
497 JSObject::cast(js_global_function->instance_prototype())); | |
498 SetProperty(prototype, Factory::constructor_symbol(), | |
499 Top::object_function(), NONE); | |
500 } else { | |
501 Handle<FunctionTemplateInfo> js_global_constructor( | |
502 FunctionTemplateInfo::cast(js_global_template->constructor())); | |
503 js_global_function = | |
504 Factory::CreateApiFunction(js_global_constructor, | |
505 Factory::InnerGlobalObject); | |
506 } | |
507 | 536 |
508 js_global_function->initial_map()->set_is_hidden_prototype(); | 537 // Step 2: create or re-initialize the global proxy object. |
509 object = Factory::NewGlobalObject(js_global_function); | 538 Handle<JSFunction> global_proxy_function; |
510 } | 539 if (global_template.IsEmpty()) { |
| 540 Handle<String> name = Handle<String>(Heap::empty_symbol()); |
| 541 Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal)); |
| 542 global_proxy_function = |
| 543 Factory::NewFunction(name, JS_GLOBAL_PROXY_TYPE, |
| 544 JSGlobalProxy::kSize, code, true); |
| 545 } else { |
| 546 Handle<ObjectTemplateInfo> data = |
| 547 v8::Utils::OpenHandle(*global_template); |
| 548 Handle<FunctionTemplateInfo> global_constructor( |
| 549 FunctionTemplateInfo::cast(data->constructor())); |
| 550 global_proxy_function = |
| 551 Factory::CreateApiFunction(global_constructor, |
| 552 Factory::OuterGlobalObject); |
| 553 } |
511 | 554 |
512 // Set the global context for the global object. | 555 Handle<String> global_name = Factory::LookupAsciiSymbol("global"); |
513 object->set_global_context(*global_context()); | 556 global_proxy_function->shared()->set_instance_class_name(*global_name); |
| 557 global_proxy_function->initial_map()->set_is_access_check_needed(true); |
514 | 558 |
515 // Step 2: create or re-initialize the global proxy object. | 559 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects |
516 Handle<JSGlobalProxy> global_proxy; | 560 // Return the global proxy. |
517 { | |
518 Handle<JSFunction> global_proxy_function; | |
519 if (global_template.IsEmpty()) { | |
520 Handle<String> name = Handle<String>(Heap::empty_symbol()); | |
521 Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal)); | |
522 global_proxy_function = | |
523 Factory::NewFunction(name, JS_GLOBAL_PROXY_TYPE, | |
524 JSGlobalProxy::kSize, code, true); | |
525 } else { | |
526 Handle<ObjectTemplateInfo> data = | |
527 v8::Utils::OpenHandle(*global_template); | |
528 Handle<FunctionTemplateInfo> global_constructor( | |
529 FunctionTemplateInfo::cast(data->constructor())); | |
530 global_proxy_function = | |
531 Factory::CreateApiFunction(global_constructor, | |
532 Factory::OuterGlobalObject); | |
533 } | |
534 | 561 |
535 Handle<String> global_name = Factory::LookupAsciiSymbol("global"); | 562 if (global_object.location() != NULL) { |
536 global_proxy_function->shared()->set_instance_class_name(*global_name); | 563 ASSERT(global_object->IsJSGlobalProxy()); |
537 global_proxy_function->initial_map()->set_is_access_check_needed(true); | 564 return ReinitializeJSGlobalProxy( |
| 565 global_proxy_function, |
| 566 Handle<JSGlobalProxy>::cast(global_object)); |
| 567 } else { |
| 568 return Handle<JSGlobalProxy>::cast( |
| 569 Factory::NewJSObject(global_proxy_function, TENURED)); |
| 570 } |
| 571 } |
538 | 572 |
539 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects | |
540 | 573 |
541 if (global_object.location() != NULL) { | 574 void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global, |
542 ASSERT(global_object->IsJSGlobalProxy()); | 575 Handle<JSGlobalProxy> global_proxy) { |
543 global_proxy = | 576 // Set the global context for the global object. |
544 ReinitializeJSGlobalProxy( | 577 inner_global->set_global_context(*global_context()); |
545 global_proxy_function, | 578 inner_global->set_global_receiver(*global_proxy); |
546 Handle<JSGlobalProxy>::cast(global_object)); | 579 global_proxy->set_context(*global_context()); |
547 } else { | 580 global_context()->set_global_proxy(*global_proxy); |
548 global_proxy = Handle<JSGlobalProxy>::cast( | 581 } |
549 Factory::NewJSObject(global_proxy_function, TENURED)); | |
550 } | |
551 | 582 |
552 // Security setup: Set the security token of the global object to | |
553 // its the inner global. This makes the security check between two | |
554 // different contexts fail by default even in case of global | |
555 // object reinitialization. | |
556 object->set_global_receiver(*global_proxy); | |
557 global_proxy->set_context(*global_context()); | |
558 } | |
559 | 583 |
560 { // --- G l o b a l C o n t e x t --- | 584 void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) { |
561 // use the empty function as closure (no scope info) | 585 Handle<GlobalObject> inner_global_from_snapshot( |
562 global_context()->set_closure(*empty_function); | 586 GlobalObject::cast(global_context_->extension())); |
563 global_context()->set_fcontext(*global_context()); | 587 Handle<JSBuiltinsObject> builtins_global(global_context_->builtins()); |
564 global_context()->set_previous(NULL); | 588 global_context_->set_extension(*inner_global); |
| 589 global_context_->set_global(*inner_global); |
| 590 global_context_->set_security_token(*inner_global); |
| 591 static const PropertyAttributes attributes = |
| 592 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); |
| 593 ForceSetProperty(builtins_global, |
| 594 Factory::LookupAsciiSymbol("global"), |
| 595 inner_global, |
| 596 attributes); |
| 597 // Setup the reference from the global object to the builtins object. |
| 598 JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global); |
| 599 TransferNamedProperties(inner_global_from_snapshot, inner_global); |
| 600 TransferIndexedProperties(inner_global_from_snapshot, inner_global); |
| 601 } |
565 | 602 |
566 // set extension and global object | |
567 global_context()->set_extension(*object); | |
568 global_context()->set_global(*object); | |
569 global_context()->set_global_proxy(*global_proxy); | |
570 // use inner global object as security token by default | |
571 global_context()->set_security_token(*object); | |
572 } | |
573 | 603 |
574 Handle<JSObject> global = Handle<JSObject>(global_context()->global()); | 604 // This is only called if we are not using snapshots. The equivalent |
575 SetProperty(global, object_name, Top::object_function(), DONT_ENUM); | 605 // work in the snapshot case is done in HookUpInnerGlobal. |
576 } | 606 void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, |
| 607 Handle<JSFunction> empty_function) { |
| 608 // --- G l o b a l C o n t e x t --- |
| 609 // Use the empty function as closure (no scope info). |
| 610 global_context()->set_closure(*empty_function); |
| 611 global_context()->set_fcontext(*global_context()); |
| 612 global_context()->set_previous(NULL); |
| 613 // Set extension and global object. |
| 614 global_context()->set_extension(*inner_global); |
| 615 global_context()->set_global(*inner_global); |
| 616 // Security setup: Set the security token of the global object to |
| 617 // its the inner global. This makes the security check between two |
| 618 // different contexts fail by default even in case of global |
| 619 // object reinitialization. |
| 620 global_context()->set_security_token(*inner_global); |
| 621 |
| 622 Handle<String> object_name = Handle<String>(Heap::Object_symbol()); |
| 623 SetProperty(inner_global, object_name, Top::object_function(), DONT_ENUM); |
577 | 624 |
578 Handle<JSObject> global = Handle<JSObject>(global_context()->global()); | 625 Handle<JSObject> global = Handle<JSObject>(global_context()->global()); |
579 | 626 |
580 // Install global Function object | 627 // Install global Function object |
581 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize, | 628 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize, |
582 empty_function, Builtins::Illegal, true); // ECMA native. | 629 empty_function, Builtins::Illegal, true); // ECMA native. |
583 | 630 |
584 { // --- A r r a y --- | 631 { // --- A r r a y --- |
585 Handle<JSFunction> array_function = | 632 Handle<JSFunction> array_function = |
586 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize, | 633 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize, |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 Handle<String> source_code = Bootstrapper::NativesSourceLookup(index); | 831 Handle<String> source_code = Bootstrapper::NativesSourceLookup(index); |
785 return CompileNative(name, source_code); | 832 return CompileNative(name, source_code); |
786 } | 833 } |
787 | 834 |
788 | 835 |
789 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) { | 836 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) { |
790 HandleScope scope; | 837 HandleScope scope; |
791 #ifdef ENABLE_DEBUGGER_SUPPORT | 838 #ifdef ENABLE_DEBUGGER_SUPPORT |
792 Debugger::set_compiling_natives(true); | 839 Debugger::set_compiling_natives(true); |
793 #endif | 840 #endif |
794 bool result = | 841 bool result = CompileScriptCached(name, |
795 CompileScriptCached(name, source, &natives_cache, NULL, true); | 842 source, |
| 843 NULL, |
| 844 NULL, |
| 845 Handle<Context>(Top::context()), |
| 846 true); |
796 ASSERT(Top::has_pending_exception() != result); | 847 ASSERT(Top::has_pending_exception() != result); |
797 if (!result) Top::clear_pending_exception(); | 848 if (!result) Top::clear_pending_exception(); |
798 #ifdef ENABLE_DEBUGGER_SUPPORT | 849 #ifdef ENABLE_DEBUGGER_SUPPORT |
799 Debugger::set_compiling_natives(false); | 850 Debugger::set_compiling_natives(false); |
800 #endif | 851 #endif |
801 return result; | 852 return result; |
802 } | 853 } |
803 | 854 |
804 | 855 |
805 bool Genesis::CompileScriptCached(Vector<const char> name, | 856 bool Genesis::CompileScriptCached(Vector<const char> name, |
806 Handle<String> source, | 857 Handle<String> source, |
807 SourceCodeCache* cache, | 858 SourceCodeCache* cache, |
808 v8::Extension* extension, | 859 v8::Extension* extension, |
| 860 Handle<Context> top_context, |
809 bool use_runtime_context) { | 861 bool use_runtime_context) { |
810 HandleScope scope; | 862 HandleScope scope; |
811 Handle<SharedFunctionInfo> function_info; | 863 Handle<SharedFunctionInfo> function_info; |
812 | 864 |
813 // If we can't find the function in the cache, we compile a new | 865 // If we can't find the function in the cache, we compile a new |
814 // function and insert it into the cache. | 866 // function and insert it into the cache. |
815 if (!cache->Lookup(name, &function_info)) { | 867 if (cache == NULL || !cache->Lookup(name, &function_info)) { |
816 ASSERT(source->IsAsciiRepresentation()); | 868 ASSERT(source->IsAsciiRepresentation()); |
817 Handle<String> script_name = Factory::NewStringFromUtf8(name); | 869 Handle<String> script_name = Factory::NewStringFromUtf8(name); |
818 function_info = Compiler::Compile( | 870 function_info = Compiler::Compile( |
819 source, | 871 source, |
820 script_name, | 872 script_name, |
821 0, | 873 0, |
822 0, | 874 0, |
823 extension, | 875 extension, |
824 NULL, | 876 NULL, |
825 Handle<String>::null(), | 877 Handle<String>::null(), |
826 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE); | 878 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE); |
827 if (function_info.is_null()) return false; | 879 if (function_info.is_null()) return false; |
828 cache->Add(name, function_info); | 880 if (cache != NULL) cache->Add(name, function_info); |
829 } | 881 } |
830 | 882 |
831 // Setup the function context. Conceptually, we should clone the | 883 // Setup the function context. Conceptually, we should clone the |
832 // function before overwriting the context but since we're in a | 884 // function before overwriting the context but since we're in a |
833 // single-threaded environment it is not strictly necessary. | 885 // single-threaded environment it is not strictly necessary. |
834 ASSERT(Top::context()->IsGlobalContext()); | 886 ASSERT(top_context->IsGlobalContext()); |
835 Handle<Context> context = | 887 Handle<Context> context = |
836 Handle<Context>(use_runtime_context | 888 Handle<Context>(use_runtime_context |
837 ? Top::context()->runtime_context() | 889 ? Handle<Context>(top_context->runtime_context()) |
838 : Top::context()); | 890 : top_context); |
839 Handle<JSFunction> fun = | 891 Handle<JSFunction> fun = |
840 Factory::NewFunctionFromSharedFunctionInfo(function_info, context); | 892 Factory::NewFunctionFromSharedFunctionInfo(function_info, context); |
841 | 893 |
842 // Call function using either the runtime object or the global | 894 // Call function using either the runtime object or the global |
843 // object as the receiver. Provide no parameters. | 895 // object as the receiver. Provide no parameters. |
844 Handle<Object> receiver = | 896 Handle<Object> receiver = |
845 Handle<Object>(use_runtime_context | 897 Handle<Object>(use_runtime_context |
846 ? Top::context()->builtins() | 898 ? top_context->builtins() |
847 : Top::context()->global()); | 899 : top_context->global()); |
848 bool has_pending_exception; | 900 bool has_pending_exception; |
849 Handle<Object> result = | 901 Handle<Object> result = |
850 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception); | 902 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception); |
851 if (has_pending_exception) return false; | 903 if (has_pending_exception) return false; |
852 return true; | 904 return true; |
853 } | 905 } |
854 | 906 |
855 | 907 |
856 #define INSTALL_NATIVE(Type, name, var) \ | 908 #define INSTALL_NATIVE(Type, name, var) \ |
857 Handle<String> var##_name = Factory::LookupAsciiSymbol(name); \ | 909 Handle<String> var##_name = Factory::LookupAsciiSymbol(name); \ |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 Factory::LookupAsciiSymbol("eval_from_function_name"), | 1091 Factory::LookupAsciiSymbol("eval_from_function_name"), |
1040 proxy_eval_from_function_name, | 1092 proxy_eval_from_function_name, |
1041 common_attributes); | 1093 common_attributes); |
1042 | 1094 |
1043 Handle<Map> script_map = Handle<Map>(script_fun->initial_map()); | 1095 Handle<Map> script_map = Handle<Map>(script_fun->initial_map()); |
1044 script_map->set_instance_descriptors(*script_descriptors); | 1096 script_map->set_instance_descriptors(*script_descriptors); |
1045 | 1097 |
1046 // Allocate the empty script. | 1098 // Allocate the empty script. |
1047 Handle<Script> script = Factory::NewScript(Factory::empty_string()); | 1099 Handle<Script> script = Factory::NewScript(Factory::empty_string()); |
1048 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 1100 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
1049 global_context()->set_empty_script(*script); | 1101 Heap::public_set_empty_script(*script); |
1050 } | 1102 } |
1051 { | 1103 { |
1052 // Builtin function for OpaqueReference -- a JSValue-based object, | 1104 // Builtin function for OpaqueReference -- a JSValue-based object, |
1053 // that keeps its field isolated from JavaScript code. It may store | 1105 // that keeps its field isolated from JavaScript code. It may store |
1054 // objects, that JavaScript code may not access. | 1106 // objects, that JavaScript code may not access. |
1055 Handle<JSFunction> opaque_reference_fun = | 1107 Handle<JSFunction> opaque_reference_fun = |
1056 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE, | 1108 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE, |
1057 JSValue::kSize, Top::initial_object_prototype(), | 1109 JSValue::kSize, Top::initial_object_prototype(), |
1058 Builtins::Illegal, false); | 1110 Builtins::Illegal, false); |
1059 Handle<JSObject> prototype = | 1111 Handle<JSObject> prototype = |
1060 Factory::NewJSObject(Top::object_function(), TENURED); | 1112 Factory::NewJSObject(Top::object_function(), TENURED); |
1061 SetPrototype(opaque_reference_fun, prototype); | 1113 SetPrototype(opaque_reference_fun, prototype); |
1062 global_context()->set_opaque_reference_function(*opaque_reference_fun); | 1114 global_context()->set_opaque_reference_function(*opaque_reference_fun); |
1063 } | 1115 } |
1064 | 1116 |
1065 if (FLAG_natives_file == NULL) { | 1117 // Install natives. |
1066 // Without natives file, install default natives. | 1118 for (int i = Natives::GetDebuggerCount(); |
1067 for (int i = Natives::GetDelayCount(); | 1119 i < Natives::GetBuiltinsCount(); |
1068 i < Natives::GetBuiltinsCount(); | 1120 i++) { |
1069 i++) { | 1121 Vector<const char> name = Natives::GetScriptName(i); |
1070 if (!CompileBuiltin(i)) return false; | 1122 if (!CompileBuiltin(i)) return false; |
1071 // TODO(ager): We really only need to install the JS builtin | 1123 // TODO(ager): We really only need to install the JS builtin |
1072 // functions on the builtins object after compiling and running | 1124 // functions on the builtins object after compiling and running |
1073 // runtime.js. | 1125 // runtime.js. |
1074 if (!InstallJSBuiltins(builtins)) return false; | 1126 if (!InstallJSBuiltins(builtins)) return false; |
1075 } | |
1076 | |
1077 // Setup natives with lazy loading. | |
1078 SetupLazy(Handle<JSFunction>(global_context()->date_function()), | |
1079 Natives::GetIndex("date"), | |
1080 Top::global_context(), | |
1081 Handle<Context>(Top::context()->runtime_context())); | |
1082 SetupLazy(Handle<JSFunction>(global_context()->regexp_function()), | |
1083 Natives::GetIndex("regexp"), | |
1084 Top::global_context(), | |
1085 Handle<Context>(Top::context()->runtime_context())); | |
1086 SetupLazy(Handle<JSObject>(global_context()->json_object()), | |
1087 Natives::GetIndex("json"), | |
1088 Top::global_context(), | |
1089 Handle<Context>(Top::context()->runtime_context())); | |
1090 | |
1091 } else if (strlen(FLAG_natives_file) != 0) { | |
1092 // Otherwise install natives from natives file if file exists and | |
1093 // compiles. | |
1094 bool exists; | |
1095 Vector<const char> source = ReadFile(FLAG_natives_file, &exists); | |
1096 Handle<String> source_string = Factory::NewStringFromAscii(source); | |
1097 if (source.is_empty()) return false; | |
1098 bool result = CompileNative(CStrVector(FLAG_natives_file), source_string); | |
1099 if (!result) return false; | |
1100 | |
1101 } else { | |
1102 // Empty natives file name - do not install any natives. | |
1103 PrintF("Warning: Running without installed natives!\n"); | |
1104 return true; | |
1105 } | 1127 } |
1106 | 1128 |
1107 InstallNativeFunctions(); | 1129 InstallNativeFunctions(); |
1108 | 1130 |
1109 // Install Function.prototype.call and apply. | 1131 // Install Function.prototype.call and apply. |
1110 { Handle<String> key = Factory::function_class_symbol(); | 1132 { Handle<String> key = Factory::function_class_symbol(); |
1111 Handle<JSFunction> function = | 1133 Handle<JSFunction> function = |
1112 Handle<JSFunction>::cast(GetProperty(Top::global(), key)); | 1134 Handle<JSFunction>::cast(GetProperty(Top::global(), key)); |
1113 Handle<JSObject> proto = | 1135 Handle<JSObject> proto = |
1114 Handle<JSObject>(JSObject::cast(function->instance_prototype())); | 1136 Handle<JSObject>(JSObject::cast(function->instance_prototype())); |
(...skipping 20 matching lines...) Expand all Loading... |
1135 apply->shared()->set_formal_parameter_count(2); | 1157 apply->shared()->set_formal_parameter_count(2); |
1136 | 1158 |
1137 // Set the lengths for the functions to satisfy ECMA-262. | 1159 // Set the lengths for the functions to satisfy ECMA-262. |
1138 call->shared()->set_length(1); | 1160 call->shared()->set_length(1); |
1139 apply->shared()->set_length(2); | 1161 apply->shared()->set_length(2); |
1140 } | 1162 } |
1141 | 1163 |
1142 #ifdef DEBUG | 1164 #ifdef DEBUG |
1143 builtins->Verify(); | 1165 builtins->Verify(); |
1144 #endif | 1166 #endif |
| 1167 |
1145 return true; | 1168 return true; |
1146 } | 1169 } |
1147 | 1170 |
1148 | 1171 |
1149 bool Genesis::InstallSpecialObjects() { | 1172 int BootstrapperActive::nesting_ = 0; |
| 1173 |
| 1174 |
| 1175 bool Bootstrapper::InstallExtensions(Handle<Context> global_context, |
| 1176 v8::ExtensionConfiguration* extensions) { |
| 1177 BootstrapperActive active; |
| 1178 SaveContext saved_context; |
| 1179 Top::set_context(*global_context); |
| 1180 if (!Genesis::InstallExtensions(global_context, extensions)) return false; |
| 1181 Genesis::InstallSpecialObjects(global_context); |
| 1182 return true; |
| 1183 } |
| 1184 |
| 1185 |
| 1186 void Genesis::InstallSpecialObjects(Handle<Context> global_context) { |
1150 HandleScope scope; | 1187 HandleScope scope; |
1151 Handle<JSGlobalObject> js_global( | 1188 Handle<JSGlobalObject> js_global( |
1152 JSGlobalObject::cast(global_context()->global())); | 1189 JSGlobalObject::cast(global_context->global())); |
1153 // Expose the natives in global if a name for it is specified. | 1190 // Expose the natives in global if a name for it is specified. |
1154 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { | 1191 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { |
1155 Handle<String> natives_string = | 1192 Handle<String> natives_string = |
1156 Factory::LookupAsciiSymbol(FLAG_expose_natives_as); | 1193 Factory::LookupAsciiSymbol(FLAG_expose_natives_as); |
1157 SetProperty(js_global, natives_string, | 1194 SetProperty(js_global, natives_string, |
1158 Handle<JSObject>(js_global->builtins()), DONT_ENUM); | 1195 Handle<JSObject>(js_global->builtins()), DONT_ENUM); |
1159 } | 1196 } |
1160 | 1197 |
1161 Handle<Object> Error = GetProperty(js_global, "Error"); | 1198 Handle<Object> Error = GetProperty(js_global, "Error"); |
1162 if (Error->IsJSObject()) { | 1199 if (Error->IsJSObject()) { |
1163 Handle<String> name = Factory::LookupAsciiSymbol("stackTraceLimit"); | 1200 Handle<String> name = Factory::LookupAsciiSymbol("stackTraceLimit"); |
1164 SetProperty(Handle<JSObject>::cast(Error), | 1201 SetProperty(Handle<JSObject>::cast(Error), |
1165 name, | 1202 name, |
1166 Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)), | 1203 Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)), |
1167 NONE); | 1204 NONE); |
1168 } | 1205 } |
1169 | 1206 |
1170 #ifdef ENABLE_DEBUGGER_SUPPORT | 1207 #ifdef ENABLE_DEBUGGER_SUPPORT |
1171 // Expose the debug global object in global if a name for it is specified. | 1208 // Expose the debug global object in global if a name for it is specified. |
1172 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { | 1209 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { |
1173 // If loading fails we just bail out without installing the | 1210 // If loading fails we just bail out without installing the |
1174 // debugger but without tanking the whole context. | 1211 // debugger but without tanking the whole context. |
1175 if (!Debug::Load()) | 1212 if (!Debug::Load()) return; |
1176 return true; | |
1177 // Set the security token for the debugger context to the same as | 1213 // Set the security token for the debugger context to the same as |
1178 // the shell global context to allow calling between these (otherwise | 1214 // the shell global context to allow calling between these (otherwise |
1179 // exposing debug global object doesn't make much sense). | 1215 // exposing debug global object doesn't make much sense). |
1180 Debug::debug_context()->set_security_token( | 1216 Debug::debug_context()->set_security_token( |
1181 global_context()->security_token()); | 1217 global_context->security_token()); |
1182 | 1218 |
1183 Handle<String> debug_string = | 1219 Handle<String> debug_string = |
1184 Factory::LookupAsciiSymbol(FLAG_expose_debug_as); | 1220 Factory::LookupAsciiSymbol(FLAG_expose_debug_as); |
1185 SetProperty(js_global, debug_string, | 1221 SetProperty(js_global, debug_string, |
1186 Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM); | 1222 Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM); |
1187 } | 1223 } |
1188 #endif | 1224 #endif |
1189 | |
1190 return true; | |
1191 } | 1225 } |
1192 | 1226 |
1193 | 1227 |
1194 bool Genesis::InstallExtensions(v8::ExtensionConfiguration* extensions) { | 1228 bool Genesis::InstallExtensions(Handle<Context> global_context, |
| 1229 v8::ExtensionConfiguration* extensions) { |
1195 // Clear coloring of extension list | 1230 // Clear coloring of extension list |
1196 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); | 1231 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); |
1197 while (current != NULL) { | 1232 while (current != NULL) { |
1198 current->set_state(v8::UNVISITED); | 1233 current->set_state(v8::UNVISITED); |
1199 current = current->next(); | 1234 current = current->next(); |
1200 } | 1235 } |
1201 // Install auto extensions | 1236 // Install auto extensions. |
1202 current = v8::RegisteredExtension::first_extension(); | 1237 current = v8::RegisteredExtension::first_extension(); |
1203 while (current != NULL) { | 1238 while (current != NULL) { |
1204 if (current->extension()->auto_enable()) | 1239 if (current->extension()->auto_enable()) |
1205 InstallExtension(current); | 1240 InstallExtension(current); |
1206 current = current->next(); | 1241 current = current->next(); |
1207 } | 1242 } |
1208 | 1243 |
1209 if (FLAG_expose_gc) InstallExtension("v8/gc"); | 1244 if (FLAG_expose_gc) InstallExtension("v8/gc"); |
1210 | 1245 |
1211 if (extensions == NULL) return true; | 1246 if (extensions == NULL) return true; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 current->set_state(v8::VISITED); | 1290 current->set_state(v8::VISITED); |
1256 v8::Extension* extension = current->extension(); | 1291 v8::Extension* extension = current->extension(); |
1257 // Install the extension's dependencies | 1292 // Install the extension's dependencies |
1258 for (int i = 0; i < extension->dependency_count(); i++) { | 1293 for (int i = 0; i < extension->dependency_count(); i++) { |
1259 if (!InstallExtension(extension->dependencies()[i])) return false; | 1294 if (!InstallExtension(extension->dependencies()[i])) return false; |
1260 } | 1295 } |
1261 Vector<const char> source = CStrVector(extension->source()); | 1296 Vector<const char> source = CStrVector(extension->source()); |
1262 Handle<String> source_code = Factory::NewStringFromAscii(source); | 1297 Handle<String> source_code = Factory::NewStringFromAscii(source); |
1263 bool result = CompileScriptCached(CStrVector(extension->name()), | 1298 bool result = CompileScriptCached(CStrVector(extension->name()), |
1264 source_code, | 1299 source_code, |
1265 &extensions_cache, extension, | 1300 &extensions_cache, |
| 1301 extension, |
| 1302 Handle<Context>(Top::context()), |
1266 false); | 1303 false); |
1267 ASSERT(Top::has_pending_exception() != result); | 1304 ASSERT(Top::has_pending_exception() != result); |
1268 if (!result) { | 1305 if (!result) { |
1269 Top::clear_pending_exception(); | 1306 Top::clear_pending_exception(); |
1270 } | 1307 } |
1271 current->set_state(v8::INSTALLED); | 1308 current->set_state(v8::INSTALLED); |
1272 return result; | 1309 return result; |
1273 } | 1310 } |
1274 | 1311 |
1275 | 1312 |
(...skipping 10 matching lines...) Expand all Loading... |
1286 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; | 1323 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; |
1287 } | 1324 } |
1288 return true; | 1325 return true; |
1289 } | 1326 } |
1290 | 1327 |
1291 | 1328 |
1292 bool Genesis::ConfigureGlobalObjects( | 1329 bool Genesis::ConfigureGlobalObjects( |
1293 v8::Handle<v8::ObjectTemplate> global_proxy_template) { | 1330 v8::Handle<v8::ObjectTemplate> global_proxy_template) { |
1294 Handle<JSObject> global_proxy( | 1331 Handle<JSObject> global_proxy( |
1295 JSObject::cast(global_context()->global_proxy())); | 1332 JSObject::cast(global_context()->global_proxy())); |
1296 Handle<JSObject> js_global(JSObject::cast(global_context()->global())); | 1333 Handle<JSObject> inner_global(JSObject::cast(global_context()->global())); |
1297 | 1334 |
1298 if (!global_proxy_template.IsEmpty()) { | 1335 if (!global_proxy_template.IsEmpty()) { |
1299 // Configure the global proxy object. | 1336 // Configure the global proxy object. |
1300 Handle<ObjectTemplateInfo> proxy_data = | 1337 Handle<ObjectTemplateInfo> proxy_data = |
1301 v8::Utils::OpenHandle(*global_proxy_template); | 1338 v8::Utils::OpenHandle(*global_proxy_template); |
1302 if (!ConfigureApiObject(global_proxy, proxy_data)) return false; | 1339 if (!ConfigureApiObject(global_proxy, proxy_data)) return false; |
1303 | 1340 |
1304 // Configure the inner global object. | 1341 // Configure the inner global object. |
1305 Handle<FunctionTemplateInfo> proxy_constructor( | 1342 Handle<FunctionTemplateInfo> proxy_constructor( |
1306 FunctionTemplateInfo::cast(proxy_data->constructor())); | 1343 FunctionTemplateInfo::cast(proxy_data->constructor())); |
1307 if (!proxy_constructor->prototype_template()->IsUndefined()) { | 1344 if (!proxy_constructor->prototype_template()->IsUndefined()) { |
1308 Handle<ObjectTemplateInfo> inner_data( | 1345 Handle<ObjectTemplateInfo> inner_data( |
1309 ObjectTemplateInfo::cast(proxy_constructor->prototype_template())); | 1346 ObjectTemplateInfo::cast(proxy_constructor->prototype_template())); |
1310 if (!ConfigureApiObject(js_global, inner_data)) return false; | 1347 if (!ConfigureApiObject(inner_global, inner_data)) return false; |
1311 } | 1348 } |
1312 } | 1349 } |
1313 | 1350 |
1314 SetObjectPrototype(global_proxy, js_global); | 1351 SetObjectPrototype(global_proxy, inner_global); |
1315 return true; | 1352 return true; |
1316 } | 1353 } |
1317 | 1354 |
1318 | 1355 |
1319 bool Genesis::ConfigureApiObject(Handle<JSObject> object, | 1356 bool Genesis::ConfigureApiObject(Handle<JSObject> object, |
1320 Handle<ObjectTemplateInfo> object_template) { | 1357 Handle<ObjectTemplateInfo> object_template) { |
1321 ASSERT(!object_template.is_null()); | 1358 ASSERT(!object_template.is_null()); |
1322 ASSERT(object->IsInstanceOf( | 1359 ASSERT(object->IsInstanceOf( |
1323 FunctionTemplateInfo::cast(object_template->constructor()))); | 1360 FunctionTemplateInfo::cast(object_template->constructor()))); |
1324 | 1361 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1358 Handle<JSFunction>(descs->GetConstantFunction(i)); | 1395 Handle<JSFunction>(descs->GetConstantFunction(i)); |
1359 SetProperty(to, key, fun, details.attributes()); | 1396 SetProperty(to, key, fun, details.attributes()); |
1360 break; | 1397 break; |
1361 } | 1398 } |
1362 case CALLBACKS: { | 1399 case CALLBACKS: { |
1363 LookupResult result; | 1400 LookupResult result; |
1364 to->LocalLookup(descs->GetKey(i), &result); | 1401 to->LocalLookup(descs->GetKey(i), &result); |
1365 // If the property is already there we skip it | 1402 // If the property is already there we skip it |
1366 if (result.IsProperty()) continue; | 1403 if (result.IsProperty()) continue; |
1367 HandleScope inner; | 1404 HandleScope inner; |
1368 Handle<DescriptorArray> inst_descs = | 1405 ASSERT(!to->HasFastProperties()); |
1369 Handle<DescriptorArray>(to->map()->instance_descriptors()); | 1406 // Add to dictionary. |
1370 Handle<String> key = Handle<String>(descs->GetKey(i)); | 1407 Handle<String> key = Handle<String>(descs->GetKey(i)); |
1371 Handle<Object> entry = Handle<Object>(descs->GetCallbacksObject(i)); | 1408 Handle<Object> callbacks(descs->GetCallbacksObject(i)); |
1372 inst_descs = Factory::CopyAppendProxyDescriptor(inst_descs, | 1409 PropertyDetails d = |
1373 key, | 1410 PropertyDetails(details.attributes(), CALLBACKS, details.index()); |
1374 entry, | 1411 SetNormalizedProperty(to, key, callbacks, d); |
1375 details.attributes()); | |
1376 to->map()->set_instance_descriptors(*inst_descs); | |
1377 break; | 1412 break; |
1378 } | 1413 } |
1379 case MAP_TRANSITION: | 1414 case MAP_TRANSITION: |
1380 case CONSTANT_TRANSITION: | 1415 case CONSTANT_TRANSITION: |
1381 case NULL_DESCRIPTOR: | 1416 case NULL_DESCRIPTOR: |
1382 // Ignore non-properties. | 1417 // Ignore non-properties. |
1383 break; | 1418 break; |
1384 case NORMAL: | 1419 case NORMAL: |
1385 // Do not occur since the from object has fast properties. | 1420 // Do not occur since the from object has fast properties. |
1386 case INTERCEPTOR: | 1421 case INTERCEPTOR: |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1451 ComputeFunctionInstanceDescriptor(false); | 1486 ComputeFunctionInstanceDescriptor(false); |
1452 Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map()); | 1487 Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map()); |
1453 fm->set_instance_descriptors(*function_map_descriptors); | 1488 fm->set_instance_descriptors(*function_map_descriptors); |
1454 Top::context()->global_context()->set_function_map(*fm); | 1489 Top::context()->global_context()->set_function_map(*fm); |
1455 } | 1490 } |
1456 | 1491 |
1457 | 1492 |
1458 Genesis::Genesis(Handle<Object> global_object, | 1493 Genesis::Genesis(Handle<Object> global_object, |
1459 v8::Handle<v8::ObjectTemplate> global_template, | 1494 v8::Handle<v8::ObjectTemplate> global_template, |
1460 v8::ExtensionConfiguration* extensions) { | 1495 v8::ExtensionConfiguration* extensions) { |
1461 // Link this genesis object into the stacked genesis chain. This | |
1462 // must be done before any early exits because the destructor | |
1463 // will always do unlinking. | |
1464 previous_ = current_; | |
1465 current_ = this; | |
1466 result_ = Handle<Context>::null(); | 1496 result_ = Handle<Context>::null(); |
1467 | |
1468 // If V8 isn't running and cannot be initialized, just return. | 1497 // If V8 isn't running and cannot be initialized, just return. |
1469 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; | 1498 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; |
1470 | 1499 |
1471 // Before creating the roots we must save the context and restore it | 1500 // Before creating the roots we must save the context and restore it |
1472 // on all function exits. | 1501 // on all function exits. |
1473 HandleScope scope; | 1502 HandleScope scope; |
1474 SaveContext context; | 1503 SaveContext saved_context; |
1475 | 1504 |
1476 CreateRoots(global_template, global_object); | 1505 Handle<Context> new_context = Snapshot::NewContextFromSnapshot(); |
| 1506 if (!new_context.is_null()) { |
| 1507 global_context_ = |
| 1508 Handle<Context>::cast(GlobalHandles::Create(*new_context)); |
| 1509 Top::set_context(*global_context_); |
| 1510 i::Counters::contexts_created_by_snapshot.Increment(); |
| 1511 result_ = global_context_; |
| 1512 JSFunction* empty_function = |
| 1513 JSFunction::cast(result_->function_map()->prototype()); |
| 1514 empty_function_ = Handle<JSFunction>(empty_function); |
| 1515 Handle<GlobalObject> inner_global; |
| 1516 Handle<JSGlobalProxy> global_proxy = |
| 1517 CreateNewGlobals(global_template, |
| 1518 global_object, |
| 1519 &inner_global); |
1477 | 1520 |
1478 if (!InstallNatives()) return; | 1521 HookUpGlobalProxy(inner_global, global_proxy); |
| 1522 HookUpInnerGlobal(inner_global); |
1479 | 1523 |
1480 MakeFunctionInstancePrototypeWritable(); | 1524 if (!ConfigureGlobalObjects(global_template)) return; |
| 1525 } else { |
| 1526 // We get here if there was no context snapshot. |
| 1527 CreateRoots(); |
| 1528 Handle<JSFunction> empty_function = CreateEmptyFunction(); |
| 1529 Handle<GlobalObject> inner_global; |
| 1530 Handle<JSGlobalProxy> global_proxy = |
| 1531 CreateNewGlobals(global_template, global_object, &inner_global); |
| 1532 HookUpGlobalProxy(inner_global, global_proxy); |
| 1533 InitializeGlobal(inner_global, empty_function); |
| 1534 if (!InstallNatives()) return; |
1481 | 1535 |
1482 if (!ConfigureGlobalObjects(global_template)) return; | 1536 MakeFunctionInstancePrototypeWritable(); |
1483 | 1537 |
1484 if (!InstallExtensions(extensions)) return; | 1538 if (!ConfigureGlobalObjects(global_template)) return; |
1485 | 1539 i::Counters::contexts_created_from_scratch.Increment(); |
1486 if (!InstallSpecialObjects()) return; | 1540 } |
1487 | 1541 |
1488 result_ = global_context_; | 1542 result_ = global_context_; |
1489 } | 1543 } |
1490 | 1544 |
1491 | 1545 |
1492 // Support for thread preemption. | 1546 // Support for thread preemption. |
1493 | 1547 |
1494 // Reserve space for statics needing saving and restoring. | 1548 // Reserve space for statics needing saving and restoring. |
1495 int Bootstrapper::ArchiveSpacePerThread() { | 1549 int Bootstrapper::ArchiveSpacePerThread() { |
1496 return Genesis::ArchiveSpacePerThread(); | 1550 return BootstrapperActive::ArchiveSpacePerThread(); |
1497 } | 1551 } |
1498 | 1552 |
1499 | 1553 |
1500 // Archive statics that are thread local. | 1554 // Archive statics that are thread local. |
1501 char* Bootstrapper::ArchiveState(char* to) { | 1555 char* Bootstrapper::ArchiveState(char* to) { |
1502 return Genesis::ArchiveState(to); | 1556 return BootstrapperActive::ArchiveState(to); |
1503 } | 1557 } |
1504 | 1558 |
1505 | 1559 |
1506 // Restore statics that are thread local. | 1560 // Restore statics that are thread local. |
1507 char* Bootstrapper::RestoreState(char* from) { | 1561 char* Bootstrapper::RestoreState(char* from) { |
1508 return Genesis::RestoreState(from); | 1562 return BootstrapperActive::RestoreState(from); |
1509 } | 1563 } |
1510 | 1564 |
1511 | 1565 |
1512 // Called when the top-level V8 mutex is destroyed. | 1566 // Called when the top-level V8 mutex is destroyed. |
1513 void Bootstrapper::FreeThreadResources() { | 1567 void Bootstrapper::FreeThreadResources() { |
1514 ASSERT(Genesis::current() == NULL); | 1568 ASSERT(!BootstrapperActive::IsActive()); |
1515 } | 1569 } |
1516 | 1570 |
1517 | 1571 |
1518 // Reserve space for statics needing saving and restoring. | 1572 // Reserve space for statics needing saving and restoring. |
1519 int Genesis::ArchiveSpacePerThread() { | 1573 int BootstrapperActive::ArchiveSpacePerThread() { |
1520 return sizeof(current_); | 1574 return sizeof(nesting_); |
1521 } | 1575 } |
1522 | 1576 |
1523 | 1577 |
1524 // Archive statics that are thread local. | 1578 // Archive statics that are thread local. |
1525 char* Genesis::ArchiveState(char* to) { | 1579 char* BootstrapperActive::ArchiveState(char* to) { |
1526 *reinterpret_cast<Genesis**>(to) = current_; | 1580 *reinterpret_cast<int*>(to) = nesting_; |
1527 current_ = NULL; | 1581 nesting_ = 0; |
1528 return to + sizeof(current_); | 1582 return to + sizeof(nesting_); |
1529 } | 1583 } |
1530 | 1584 |
1531 | 1585 |
1532 // Restore statics that are thread local. | 1586 // Restore statics that are thread local. |
1533 char* Genesis::RestoreState(char* from) { | 1587 char* BootstrapperActive::RestoreState(char* from) { |
1534 current_ = *reinterpret_cast<Genesis**>(from); | 1588 nesting_ = *reinterpret_cast<int*>(from); |
1535 return from + sizeof(current_); | 1589 return from + sizeof(nesting_); |
1536 } | 1590 } |
1537 | 1591 |
1538 } } // namespace v8::internal | 1592 } } // namespace v8::internal |
OLD | NEW |