Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 204 void InitializeExperimentalGlobal(); | 204 void InitializeExperimentalGlobal(); |
| 205 // Installs the contents of the native .js files on the global objects. | 205 // Installs the contents of the native .js files on the global objects. |
| 206 // Used for creating a context from scratch. | 206 // Used for creating a context from scratch. |
| 207 void InstallNativeFunctions(); | 207 void InstallNativeFunctions(); |
| 208 void InstallExperimentalNativeFunctions(); | 208 void InstallExperimentalNativeFunctions(); |
| 209 bool InstallNatives(); | 209 bool InstallNatives(); |
| 210 bool InstallExperimentalNatives(); | 210 bool InstallExperimentalNatives(); |
| 211 void InstallBuiltinFunctionIds(); | 211 void InstallBuiltinFunctionIds(); |
| 212 void InstallJSFunctionResultCaches(); | 212 void InstallJSFunctionResultCaches(); |
| 213 void InitializeNormalizedMapCaches(); | 213 void InitializeNormalizedMapCaches(); |
| 214 enum ExtensionTraversalState { | |
|
Vitaly Repeshko
2011/11/15 22:13:02
nit: Insert a blank line.
| |
| 215 UNVISITED, VISITED, INSTALLED | |
| 216 }; | |
| 217 | |
| 218 class ExtensionStates { | |
| 219 public: | |
| 220 ExtensionStates(); | |
| 221 ExtensionTraversalState get_state(RegisteredExtension* extension); | |
| 222 void set_state(RegisteredExtension* extension, | |
| 223 ExtensionTraversalState state); | |
| 224 private: | |
| 225 HashMap map_; | |
| 226 }; | |
|
Vitaly Repeshko
2011/11/15 22:13:02
nit: DISALLOW_COPY_AND_ASSIGN.
| |
| 227 | |
| 214 // Used both for deserialized and from-scratch contexts to add the extensions | 228 // Used both for deserialized and from-scratch contexts to add the extensions |
| 215 // provided. | 229 // provided. |
| 216 static bool InstallExtensions(Handle<Context> global_context, | 230 static bool InstallExtensions(Handle<Context> global_context, |
| 217 v8::ExtensionConfiguration* extensions); | 231 v8::ExtensionConfiguration* extensions); |
| 218 static bool InstallExtension(const char* name); | 232 static bool InstallExtension(const char* name, |
| 219 static bool InstallExtension(v8::RegisteredExtension* current); | 233 ExtensionStates* extension_states); |
| 234 static bool InstallExtension(v8::RegisteredExtension* current, | |
| 235 ExtensionStates* extension_states); | |
| 220 static void InstallSpecialObjects(Handle<Context> global_context); | 236 static void InstallSpecialObjects(Handle<Context> global_context); |
| 221 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); | 237 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); |
| 222 bool ConfigureApiObject(Handle<JSObject> object, | 238 bool ConfigureApiObject(Handle<JSObject> object, |
| 223 Handle<ObjectTemplateInfo> object_template); | 239 Handle<ObjectTemplateInfo> object_template); |
| 224 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); | 240 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); |
| 225 | 241 |
| 226 // Migrates all properties from the 'from' object to the 'to' | 242 // Migrates all properties from the 'from' object to the 'to' |
| 227 // object and overrides the prototype in 'to' with the one from | 243 // object and overrides the prototype in 'to' with the one from |
| 228 // 'from'. | 244 // 'from'. |
| 229 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 245 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
| (...skipping 1698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1928 global_context->security_token()); | 1944 global_context->security_token()); |
| 1929 | 1945 |
| 1930 Handle<String> debug_string = | 1946 Handle<String> debug_string = |
| 1931 factory->LookupAsciiSymbol(FLAG_expose_debug_as); | 1947 factory->LookupAsciiSymbol(FLAG_expose_debug_as); |
| 1932 Handle<Object> global_proxy(debug->debug_context()->global_proxy()); | 1948 Handle<Object> global_proxy(debug->debug_context()->global_proxy()); |
| 1933 SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM); | 1949 SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM); |
| 1934 } | 1950 } |
| 1935 #endif | 1951 #endif |
| 1936 } | 1952 } |
| 1937 | 1953 |
| 1954 static uint32_t Hash(RegisteredExtension* extension) { | |
| 1955 return v8::internal::ComputeIntegerHash( | |
|
Vitaly Repeshko
2011/11/15 22:13:02
Oh, actually there's already ComputePointerHash in
| |
| 1956 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(extension))); | |
| 1957 } | |
| 1958 | |
| 1959 static bool MatchRegisteredExtensions(void* key1, void* key2) { | |
| 1960 return key1 == key2; | |
| 1961 } | |
| 1962 | |
| 1963 static Allocator* ExtensionStatesAllocator() { | |
| 1964 static Allocator default_allocator; | |
| 1965 return &default_allocator; | |
| 1966 } | |
| 1967 | |
| 1968 Genesis::ExtensionStates::ExtensionStates() | |
| 1969 : map_(MatchRegisteredExtensions, ExtensionStatesAllocator(), 8) | |
|
Vitaly Repeshko
2011/11/15 22:13:02
... and does the default allocator (if you omit ar
| |
| 1970 {} | |
| 1971 | |
| 1972 Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state( | |
| 1973 RegisteredExtension* extension) { | |
| 1974 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false); | |
| 1975 if (entry == NULL) { | |
| 1976 return UNVISITED; | |
| 1977 } | |
| 1978 return static_cast<ExtensionTraversalState>( | |
| 1979 reinterpret_cast<intptr_t>(entry->value)); | |
| 1980 } | |
| 1981 | |
| 1982 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension, | |
| 1983 Genesis::ExtensionTraversalState state) { | |
|
Vitaly Repeshko
2011/11/15 22:13:02
nit: Formatting.
| |
| 1984 map_.Lookup(extension, Hash(extension), true)->value = | |
| 1985 reinterpret_cast<void*>(static_cast<intptr_t>(state)); | |
| 1986 } | |
| 1938 | 1987 |
| 1939 bool Genesis::InstallExtensions(Handle<Context> global_context, | 1988 bool Genesis::InstallExtensions(Handle<Context> global_context, |
| 1940 v8::ExtensionConfiguration* extensions) { | 1989 v8::ExtensionConfiguration* extensions) { |
| 1941 // TODO(isolates): Extensions on multiple isolates may take a little more | 1990 // TODO(isolates): Extensions on multiple isolates may take a little more |
| 1942 // effort. (The external API reads 'ignore'-- does that mean | 1991 // effort. (The external API reads 'ignore'-- does that mean |
| 1943 // we can break the interface?) | 1992 // we can break the interface?) |
| 1944 | 1993 |
| 1945 // Clear coloring of extension list | 1994 ExtensionStates extension_states; // All extensions have state UNVISITED. |
| 1995 // Install auto extensions. | |
| 1946 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); | 1996 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); |
| 1947 while (current != NULL) { | 1997 while (current != NULL) { |
| 1948 current->set_state(v8::UNVISITED); | |
| 1949 current = current->next(); | |
| 1950 } | |
| 1951 // Install auto extensions. | |
| 1952 current = v8::RegisteredExtension::first_extension(); | |
| 1953 while (current != NULL) { | |
| 1954 if (current->extension()->auto_enable()) | 1998 if (current->extension()->auto_enable()) |
| 1955 InstallExtension(current); | 1999 InstallExtension(current, &extension_states); |
| 1956 current = current->next(); | 2000 current = current->next(); |
| 1957 } | 2001 } |
| 1958 | 2002 |
| 1959 if (FLAG_expose_gc) InstallExtension("v8/gc"); | 2003 if (FLAG_expose_gc) InstallExtension("v8/gc", &extension_states); |
| 1960 if (FLAG_expose_externalize_string) InstallExtension("v8/externalize"); | 2004 if (FLAG_expose_externalize_string) { |
| 2005 InstallExtension("v8/externalize", &extension_states); | |
| 2006 } | |
| 1961 | 2007 |
| 1962 if (extensions == NULL) return true; | 2008 if (extensions == NULL) return true; |
| 1963 // Install required extensions | 2009 // Install required extensions |
| 1964 int count = v8::ImplementationUtilities::GetNameCount(extensions); | 2010 int count = v8::ImplementationUtilities::GetNameCount(extensions); |
| 1965 const char** names = v8::ImplementationUtilities::GetNames(extensions); | 2011 const char** names = v8::ImplementationUtilities::GetNames(extensions); |
| 1966 for (int i = 0; i < count; i++) { | 2012 for (int i = 0; i < count; i++) { |
| 1967 if (!InstallExtension(names[i])) | 2013 if (!InstallExtension(names[i], &extension_states)) |
| 1968 return false; | 2014 return false; |
| 1969 } | 2015 } |
| 1970 | 2016 |
| 1971 return true; | 2017 return true; |
| 1972 } | 2018 } |
| 1973 | 2019 |
| 1974 | 2020 |
| 1975 // Installs a named extension. This methods is unoptimized and does | 2021 // Installs a named extension. This methods is unoptimized and does |
| 1976 // not scale well if we want to support a large number of extensions. | 2022 // not scale well if we want to support a large number of extensions. |
| 1977 bool Genesis::InstallExtension(const char* name) { | 2023 bool Genesis::InstallExtension(const char* name, |
| 2024 ExtensionStates* extension_states) { | |
| 1978 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); | 2025 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension(); |
| 1979 // Loop until we find the relevant extension | 2026 // Loop until we find the relevant extension |
| 1980 while (current != NULL) { | 2027 while (current != NULL) { |
| 1981 if (strcmp(name, current->extension()->name()) == 0) break; | 2028 if (strcmp(name, current->extension()->name()) == 0) break; |
| 1982 current = current->next(); | 2029 current = current->next(); |
| 1983 } | 2030 } |
| 1984 // Didn't find the extension; fail. | 2031 // Didn't find the extension; fail. |
| 1985 if (current == NULL) { | 2032 if (current == NULL) { |
| 1986 v8::Utils::ReportApiFailure( | 2033 v8::Utils::ReportApiFailure( |
| 1987 "v8::Context::New()", "Cannot find required extension"); | 2034 "v8::Context::New()", "Cannot find required extension"); |
| 1988 return false; | 2035 return false; |
| 1989 } | 2036 } |
| 1990 return InstallExtension(current); | 2037 return InstallExtension(current, extension_states); |
| 1991 } | 2038 } |
| 1992 | 2039 |
| 1993 | 2040 |
| 1994 bool Genesis::InstallExtension(v8::RegisteredExtension* current) { | 2041 bool Genesis::InstallExtension(v8::RegisteredExtension* current, ExtensionStates * extension_states) { |
|
Vitaly Repeshko
2011/11/15 22:13:02
nit: Formatting.
| |
| 1995 HandleScope scope; | 2042 HandleScope scope; |
| 1996 | 2043 |
| 1997 if (current->state() == v8::INSTALLED) return true; | 2044 if (extension_states->get_state(current) == INSTALLED) return true; |
| 1998 // The current node has already been visited so there must be a | 2045 // The current node has already been visited so there must be a |
| 1999 // cycle in the dependency graph; fail. | 2046 // cycle in the dependency graph; fail. |
| 2000 if (current->state() == v8::VISITED) { | 2047 if (extension_states->get_state(current) == VISITED) { |
| 2001 v8::Utils::ReportApiFailure( | 2048 v8::Utils::ReportApiFailure( |
| 2002 "v8::Context::New()", "Circular extension dependency"); | 2049 "v8::Context::New()", "Circular extension dependency"); |
| 2003 return false; | 2050 return false; |
| 2004 } | 2051 } |
| 2005 ASSERT(current->state() == v8::UNVISITED); | 2052 ASSERT(extension_states->get_state(current) == UNVISITED); |
| 2006 current->set_state(v8::VISITED); | 2053 extension_states->set_state(current, VISITED); |
| 2007 v8::Extension* extension = current->extension(); | 2054 v8::Extension* extension = current->extension(); |
| 2008 // Install the extension's dependencies | 2055 // Install the extension's dependencies |
| 2009 for (int i = 0; i < extension->dependency_count(); i++) { | 2056 for (int i = 0; i < extension->dependency_count(); i++) { |
| 2010 if (!InstallExtension(extension->dependencies()[i])) return false; | 2057 if (!InstallExtension(extension->dependencies()[i], extension_states)) |
| 2058 return false; | |
| 2011 } | 2059 } |
| 2012 Isolate* isolate = Isolate::Current(); | 2060 Isolate* isolate = Isolate::Current(); |
| 2013 Handle<String> source_code = | 2061 Handle<String> source_code = |
| 2014 isolate->factory()->NewExternalStringFromAscii(extension->source()); | 2062 isolate->factory()->NewExternalStringFromAscii(extension->source()); |
| 2015 bool result = CompileScriptCached( | 2063 bool result = CompileScriptCached( |
| 2016 CStrVector(extension->name()), | 2064 CStrVector(extension->name()), |
| 2017 source_code, | 2065 source_code, |
| 2018 isolate->bootstrapper()->extensions_cache(), | 2066 isolate->bootstrapper()->extensions_cache(), |
| 2019 extension, | 2067 extension, |
| 2020 Handle<Context>(isolate->context()), | 2068 Handle<Context>(isolate->context()), |
| 2021 false); | 2069 false); |
| 2022 ASSERT(isolate->has_pending_exception() != result); | 2070 ASSERT(isolate->has_pending_exception() != result); |
| 2023 if (!result) { | 2071 if (!result) { |
| 2024 // We print out the name of the extension that fail to install. | 2072 // We print out the name of the extension that fail to install. |
| 2025 // When an error is thrown during bootstrapping we automatically print | 2073 // When an error is thrown during bootstrapping we automatically print |
| 2026 // the line number at which this happened to the console in the isolate | 2074 // the line number at which this happened to the console in the isolate |
| 2027 // error throwing functionality. | 2075 // error throwing functionality. |
| 2028 OS::PrintError("Error installing extension '%s'.\n", | 2076 OS::PrintError("Error installing extension '%s'.\n", |
| 2029 current->extension()->name()); | 2077 current->extension()->name()); |
| 2030 isolate->clear_pending_exception(); | 2078 isolate->clear_pending_exception(); |
| 2031 } | 2079 } |
| 2032 current->set_state(v8::INSTALLED); | 2080 extension_states->set_state(current, INSTALLED); |
| 2081 isolate->extension_installed(); | |
| 2033 return result; | 2082 return result; |
| 2034 } | 2083 } |
| 2035 | 2084 |
| 2036 | 2085 |
| 2037 bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) { | 2086 bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) { |
| 2038 HandleScope scope; | 2087 HandleScope scope; |
| 2039 Factory* factory = builtins->GetIsolate()->factory(); | 2088 Factory* factory = builtins->GetIsolate()->factory(); |
| 2040 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { | 2089 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) { |
| 2041 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); | 2090 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i); |
| 2042 Handle<String> name = factory->LookupAsciiSymbol(Builtins::GetName(id)); | 2091 Handle<String> name = factory->LookupAsciiSymbol(Builtins::GetName(id)); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2306 return from + sizeof(NestingCounterType); | 2355 return from + sizeof(NestingCounterType); |
| 2307 } | 2356 } |
| 2308 | 2357 |
| 2309 | 2358 |
| 2310 // Called when the top-level V8 mutex is destroyed. | 2359 // Called when the top-level V8 mutex is destroyed. |
| 2311 void Bootstrapper::FreeThreadResources() { | 2360 void Bootstrapper::FreeThreadResources() { |
| 2312 ASSERT(!IsActive()); | 2361 ASSERT(!IsActive()); |
| 2313 } | 2362 } |
| 2314 | 2363 |
| 2315 } } // namespace v8::internal | 2364 } } // namespace v8::internal |
| OLD | NEW |