OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 return Handle<String>::cast(cached_source); | 95 return Handle<String>::cast(cached_source); |
96 } | 96 } |
97 | 97 |
98 | 98 |
99 void Bootstrapper::Initialize(bool create_heap_objects) { | 99 void Bootstrapper::Initialize(bool create_heap_objects) { |
100 extensions_cache_.Initialize(isolate_, create_heap_objects); | 100 extensions_cache_.Initialize(isolate_, create_heap_objects); |
101 } | 101 } |
102 | 102 |
103 | 103 |
104 void Bootstrapper::InitializeOncePerProcess() { | 104 void Bootstrapper::InitializeOncePerProcess() { |
105 #ifdef ADDRESS_SANITIZER | |
106 FreeBufferExtension::Register(); | 105 FreeBufferExtension::Register(); |
107 #endif | |
108 GCExtension::Register(); | 106 GCExtension::Register(); |
109 ExternalizeStringExtension::Register(); | 107 ExternalizeStringExtension::Register(); |
110 StatisticsExtension::Register(); | 108 StatisticsExtension::Register(); |
111 TriggerFailureExtension::Register(); | 109 TriggerFailureExtension::Register(); |
112 } | 110 } |
113 | 111 |
114 | 112 |
115 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { | 113 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { |
116 char* memory = new char[bytes]; | 114 char* memory = new char[bytes]; |
117 if (memory != NULL) { | 115 if (memory != NULL) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 ExtensionTraversalState state); | 229 ExtensionTraversalState state); |
232 private: | 230 private: |
233 HashMap map_; | 231 HashMap map_; |
234 DISALLOW_COPY_AND_ASSIGN(ExtensionStates); | 232 DISALLOW_COPY_AND_ASSIGN(ExtensionStates); |
235 }; | 233 }; |
236 | 234 |
237 // Used both for deserialized and from-scratch contexts to add the extensions | 235 // Used both for deserialized and from-scratch contexts to add the extensions |
238 // provided. | 236 // provided. |
239 static bool InstallExtensions(Handle<Context> native_context, | 237 static bool InstallExtensions(Handle<Context> native_context, |
240 v8::ExtensionConfiguration* extensions); | 238 v8::ExtensionConfiguration* extensions); |
| 239 static bool InstallAutoExtensions(Isolate* isolate, |
| 240 ExtensionStates* extension_states); |
| 241 static bool InstallRequestedExtensions(Isolate* isolate, |
| 242 v8::ExtensionConfiguration* extensions, |
| 243 ExtensionStates* extension_states); |
241 static bool InstallExtension(Isolate* isolate, | 244 static bool InstallExtension(Isolate* isolate, |
242 const char* name, | 245 const char* name, |
243 ExtensionStates* extension_states); | 246 ExtensionStates* extension_states); |
244 static bool InstallExtension(Isolate* isolate, | 247 static bool InstallExtension(Isolate* isolate, |
245 v8::RegisteredExtension* current, | 248 v8::RegisteredExtension* current, |
246 ExtensionStates* extension_states); | 249 ExtensionStates* extension_states); |
247 static void InstallSpecialObjects(Handle<Context> native_context); | 250 static bool InstallSpecialObjects(Handle<Context> native_context); |
248 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); | 251 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); |
249 bool ConfigureApiObject(Handle<JSObject> object, | 252 bool ConfigureApiObject(Handle<JSObject> object, |
250 Handle<ObjectTemplateInfo> object_template); | 253 Handle<ObjectTemplateInfo> object_template); |
251 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); | 254 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); |
252 | 255 |
253 // Migrates all properties from the 'from' object to the 'to' | 256 // Migrates all properties from the 'from' object to the 'to' |
254 // object and overrides the prototype in 'to' with the one from | 257 // object and overrides the prototype in 'to' with the one from |
255 // 'from'. | 258 // 'from'. |
256 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 259 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
257 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); | 260 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
(...skipping 1887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2145 factory()->NewFixedArray(NormalizedMapCache::kEntries, TENURED)); | 2148 factory()->NewFixedArray(NormalizedMapCache::kEntries, TENURED)); |
2146 native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array)); | 2149 native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array)); |
2147 } | 2150 } |
2148 | 2151 |
2149 | 2152 |
2150 bool Bootstrapper::InstallExtensions(Handle<Context> native_context, | 2153 bool Bootstrapper::InstallExtensions(Handle<Context> native_context, |
2151 v8::ExtensionConfiguration* extensions) { | 2154 v8::ExtensionConfiguration* extensions) { |
2152 BootstrapperActive active(this); | 2155 BootstrapperActive active(this); |
2153 SaveContext saved_context(isolate_); | 2156 SaveContext saved_context(isolate_); |
2154 isolate_->set_context(*native_context); | 2157 isolate_->set_context(*native_context); |
2155 if (!Genesis::InstallExtensions(native_context, extensions)) return false; | 2158 return Genesis::InstallExtensions(native_context, extensions) && |
2156 Genesis::InstallSpecialObjects(native_context); | 2159 Genesis::InstallSpecialObjects(native_context); |
2157 return true; | |
2158 } | 2160 } |
2159 | 2161 |
2160 | 2162 |
2161 void Genesis::InstallSpecialObjects(Handle<Context> native_context) { | 2163 bool Genesis::InstallSpecialObjects(Handle<Context> native_context) { |
2162 Isolate* isolate = native_context->GetIsolate(); | 2164 Isolate* isolate = native_context->GetIsolate(); |
2163 Factory* factory = isolate->factory(); | 2165 Factory* factory = isolate->factory(); |
2164 HandleScope scope(isolate); | 2166 HandleScope scope(isolate); |
2165 Handle<JSGlobalObject> global(JSGlobalObject::cast( | 2167 Handle<JSGlobalObject> global(JSGlobalObject::cast( |
2166 native_context->global_object())); | 2168 native_context->global_object())); |
2167 // Expose the natives in global if a name for it is specified. | 2169 // Expose the natives in global if a name for it is specified. |
2168 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { | 2170 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { |
2169 Handle<String> natives = | 2171 Handle<String> natives = |
2170 factory->InternalizeUtf8String(FLAG_expose_natives_as); | 2172 factory->InternalizeUtf8String(FLAG_expose_natives_as); |
2171 CHECK_NOT_EMPTY_HANDLE(isolate, | 2173 JSObject::SetLocalPropertyIgnoreAttributes( |
2172 JSObject::SetLocalPropertyIgnoreAttributes( | 2174 global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM); |
2173 global, natives, | 2175 if (isolate->has_pending_exception()) return false; |
2174 Handle<JSObject>(global->builtins()), | |
2175 DONT_ENUM)); | |
2176 } | 2176 } |
2177 | 2177 |
2178 Handle<Object> Error = GetProperty(global, "Error"); | 2178 Handle<Object> Error = GetProperty(global, "Error"); |
2179 if (Error->IsJSObject()) { | 2179 if (Error->IsJSObject()) { |
2180 Handle<String> name = factory->InternalizeOneByteString( | 2180 Handle<String> name = factory->InternalizeOneByteString( |
2181 STATIC_ASCII_VECTOR("stackTraceLimit")); | 2181 STATIC_ASCII_VECTOR("stackTraceLimit")); |
2182 Handle<Smi> stack_trace_limit( | 2182 Handle<Smi> stack_trace_limit( |
2183 Smi::FromInt(FLAG_stack_trace_limit), isolate); | 2183 Smi::FromInt(FLAG_stack_trace_limit), isolate); |
2184 CHECK_NOT_EMPTY_HANDLE(isolate, | 2184 JSObject::SetLocalPropertyIgnoreAttributes( |
2185 JSObject::SetLocalPropertyIgnoreAttributes( | 2185 Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE); |
2186 Handle<JSObject>::cast(Error), name, | 2186 if (isolate->has_pending_exception()) return false; |
2187 stack_trace_limit, NONE)); | |
2188 } | 2187 } |
2189 | 2188 |
2190 #ifdef ENABLE_DEBUGGER_SUPPORT | 2189 #ifdef ENABLE_DEBUGGER_SUPPORT |
2191 // Expose the debug global object in global if a name for it is specified. | 2190 // Expose the debug global object in global if a name for it is specified. |
2192 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { | 2191 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) { |
2193 Debug* debug = isolate->debug(); | 2192 Debug* debug = isolate->debug(); |
2194 // If loading fails we just bail out without installing the | 2193 // If loading fails we just bail out without installing the |
2195 // debugger but without tanking the whole context. | 2194 // debugger but without tanking the whole context. |
2196 if (!debug->Load()) return; | 2195 if (!debug->Load()) return true; |
2197 // Set the security token for the debugger context to the same as | 2196 // Set the security token for the debugger context to the same as |
2198 // the shell native context to allow calling between these (otherwise | 2197 // the shell native context to allow calling between these (otherwise |
2199 // exposing debug global object doesn't make much sense). | 2198 // exposing debug global object doesn't make much sense). |
2200 debug->debug_context()->set_security_token( | 2199 debug->debug_context()->set_security_token( |
2201 native_context->security_token()); | 2200 native_context->security_token()); |
2202 | 2201 |
2203 Handle<String> debug_string = | 2202 Handle<String> debug_string = |
2204 factory->InternalizeUtf8String(FLAG_expose_debug_as); | 2203 factory->InternalizeUtf8String(FLAG_expose_debug_as); |
2205 Handle<Object> global_proxy( | 2204 Handle<Object> global_proxy( |
2206 debug->debug_context()->global_proxy(), isolate); | 2205 debug->debug_context()->global_proxy(), isolate); |
2207 CHECK_NOT_EMPTY_HANDLE(isolate, | 2206 JSObject::SetLocalPropertyIgnoreAttributes( |
2208 JSObject::SetLocalPropertyIgnoreAttributes( | 2207 global, debug_string, global_proxy, DONT_ENUM); |
2209 global, debug_string, global_proxy, DONT_ENUM)); | 2208 if (isolate->has_pending_exception()) return false; |
2210 } | 2209 } |
2211 #endif | 2210 #endif |
| 2211 return true; |
2212 } | 2212 } |
2213 | 2213 |
2214 | 2214 |
2215 static uint32_t Hash(RegisteredExtension* extension) { | 2215 static uint32_t Hash(RegisteredExtension* extension) { |
2216 return v8::internal::ComputePointerHash(extension); | 2216 return v8::internal::ComputePointerHash(extension); |
2217 } | 2217 } |
2218 | 2218 |
2219 | 2219 |
2220 static bool MatchRegisteredExtensions(void* key1, void* key2) { | 2220 static bool MatchRegisteredExtensions(void* key1, void* key2) { |
2221 return key1 == key2; | 2221 return key1 == key2; |
(...skipping 11 matching lines...) Expand all Loading... |
2233 return static_cast<ExtensionTraversalState>( | 2233 return static_cast<ExtensionTraversalState>( |
2234 reinterpret_cast<intptr_t>(entry->value)); | 2234 reinterpret_cast<intptr_t>(entry->value)); |
2235 } | 2235 } |
2236 | 2236 |
2237 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension, | 2237 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension, |
2238 ExtensionTraversalState state) { | 2238 ExtensionTraversalState state) { |
2239 map_.Lookup(extension, Hash(extension), true)->value = | 2239 map_.Lookup(extension, Hash(extension), true)->value = |
2240 reinterpret_cast<void*>(static_cast<intptr_t>(state)); | 2240 reinterpret_cast<void*>(static_cast<intptr_t>(state)); |
2241 } | 2241 } |
2242 | 2242 |
| 2243 |
2243 bool Genesis::InstallExtensions(Handle<Context> native_context, | 2244 bool Genesis::InstallExtensions(Handle<Context> native_context, |
2244 v8::ExtensionConfiguration* extensions) { | 2245 v8::ExtensionConfiguration* extensions) { |
2245 Isolate* isolate = native_context->GetIsolate(); | 2246 Isolate* isolate = native_context->GetIsolate(); |
2246 ExtensionStates extension_states; // All extensions have state UNVISITED. | 2247 ExtensionStates extension_states; // All extensions have state UNVISITED. |
2247 // Install auto extensions. | 2248 return InstallAutoExtensions(isolate, &extension_states) && |
2248 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); | 2249 (!FLAG_expose_free_buffer || |
2249 while (current != NULL) { | 2250 InstallExtension(isolate, "v8/free-buffer", &extension_states)) && |
2250 if (current->extension()->auto_enable()) | 2251 (!FLAG_expose_gc || |
2251 InstallExtension(isolate, current, &extension_states); | 2252 InstallExtension(isolate, "v8/gc", &extension_states)) && |
2252 current = current->next(); | 2253 (!FLAG_expose_externalize_string || |
| 2254 InstallExtension(isolate, "v8/externalize", &extension_states)) && |
| 2255 (!FLAG_track_gc_object_stats || |
| 2256 InstallExtension(isolate, "v8/statistics", &extension_states)) && |
| 2257 (!FLAG_expose_trigger_failure || |
| 2258 InstallExtension(isolate, "v8/trigger-failure", &extension_states)) && |
| 2259 InstallRequestedExtensions(isolate, extensions, &extension_states); |
| 2260 } |
| 2261 |
| 2262 |
| 2263 bool Genesis::InstallAutoExtensions(Isolate* isolate, |
| 2264 ExtensionStates* extension_states) { |
| 2265 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension(); |
| 2266 it != NULL; |
| 2267 it = it->next()) { |
| 2268 if (it->extension()->auto_enable() && |
| 2269 !InstallExtension(isolate, it, extension_states)) { |
| 2270 return false; |
| 2271 } |
2253 } | 2272 } |
2254 | |
2255 #ifdef ADDRESS_SANITIZER | |
2256 if (FLAG_expose_free_buffer) { | |
2257 InstallExtension(isolate, "v8/free-buffer", &extension_states); | |
2258 } | |
2259 #endif | |
2260 if (FLAG_expose_gc) InstallExtension(isolate, "v8/gc", &extension_states); | |
2261 if (FLAG_expose_externalize_string) { | |
2262 InstallExtension(isolate, "v8/externalize", &extension_states); | |
2263 } | |
2264 if (FLAG_track_gc_object_stats) { | |
2265 InstallExtension(isolate, "v8/statistics", &extension_states); | |
2266 } | |
2267 if (FLAG_expose_trigger_failure) { | |
2268 InstallExtension(isolate, "v8/trigger-failure", &extension_states); | |
2269 } | |
2270 | |
2271 for (const char** it = extensions->begin(); it != extensions->end(); ++it) { | |
2272 if (!InstallExtension(isolate, *it, &extension_states)) return false; | |
2273 } | |
2274 | |
2275 return true; | 2273 return true; |
2276 } | 2274 } |
2277 | 2275 |
| 2276 |
| 2277 bool Genesis::InstallRequestedExtensions(Isolate* isolate, |
| 2278 v8::ExtensionConfiguration* extensions, |
| 2279 ExtensionStates* extension_states) { |
| 2280 for (const char** it = extensions->begin(); it != extensions->end(); ++it) { |
| 2281 if (!InstallExtension(isolate, *it, extension_states)) return false; |
| 2282 } |
| 2283 return true; |
| 2284 } |
| 2285 |
2278 | 2286 |
2279 // Installs a named extension. This methods is unoptimized and does | 2287 // Installs a named extension. This methods is unoptimized and does |
2280 // not scale well if we want to support a large number of extensions. | 2288 // not scale well if we want to support a large number of extensions. |
2281 bool Genesis::InstallExtension(Isolate* isolate, | 2289 bool Genesis::InstallExtension(Isolate* isolate, |
2282 const char* name, | 2290 const char* name, |
2283 ExtensionStates* extension_states) { | 2291 ExtensionStates* extension_states) { |
2284 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); | 2292 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension(); |
2285 // Loop until we find the relevant extension | 2293 it != NULL; |
2286 while (current != NULL) { | 2294 it = it->next()) { |
2287 if (strcmp(name, current->extension()->name()) == 0) break; | 2295 if (strcmp(name, it->extension()->name()) == 0) { |
2288 current = current->next(); | 2296 return InstallExtension(isolate, it, extension_states); |
| 2297 } |
2289 } | 2298 } |
2290 // Didn't find the extension; fail. | 2299 return Utils::ApiCheck(false, |
2291 if (!Utils::ApiCheck(current != NULL, | 2300 "v8::Context::New()", |
2292 "v8::Context::New()", | 2301 "Cannot find required extension"); |
2293 "Cannot find required extension")) { | |
2294 return false; | |
2295 } | |
2296 return InstallExtension(isolate, current, extension_states); | |
2297 } | 2302 } |
2298 | 2303 |
2299 | 2304 |
2300 bool Genesis::InstallExtension(Isolate* isolate, | 2305 bool Genesis::InstallExtension(Isolate* isolate, |
2301 v8::RegisteredExtension* current, | 2306 v8::RegisteredExtension* current, |
2302 ExtensionStates* extension_states) { | 2307 ExtensionStates* extension_states) { |
2303 HandleScope scope(isolate); | 2308 HandleScope scope(isolate); |
2304 | 2309 |
2305 if (extension_states->get_state(current) == INSTALLED) return true; | 2310 if (extension_states->get_state(current) == INSTALLED) return true; |
2306 // The current node has already been visited so there must be a | 2311 // The current node has already been visited so there must be a |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2699 return from + sizeof(NestingCounterType); | 2704 return from + sizeof(NestingCounterType); |
2700 } | 2705 } |
2701 | 2706 |
2702 | 2707 |
2703 // Called when the top-level V8 mutex is destroyed. | 2708 // Called when the top-level V8 mutex is destroyed. |
2704 void Bootstrapper::FreeThreadResources() { | 2709 void Bootstrapper::FreeThreadResources() { |
2705 ASSERT(!IsActive()); | 2710 ASSERT(!IsActive()); |
2706 } | 2711 } |
2707 | 2712 |
2708 } } // namespace v8::internal | 2713 } } // namespace v8::internal |
OLD | NEW |