OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CHROME_RENDERER_MODULE_SYSTEM_H_ | |
6 #define CHROME_RENDERER_MODULE_SYSTEM_H_ | |
7 | |
8 #include "base/compiler_specific.h" | |
9 #include "base/memory/linked_ptr.h" | |
10 #include "base/memory/scoped_ptr.h" | |
11 #include "chrome/renderer/native_handler.h" | |
12 #include "v8/include/v8.h" | |
13 | |
14 #include <map> | |
15 #include <set> | |
16 #include <string> | |
17 | |
18 // A module system for JS similar to node.js' require() function. | |
19 // Each module has three variables in the global scope: | |
20 // - exports, an object returned to dependencies who require() this | |
21 // module. | |
22 // - require, a function that takes a module name as an argument and returns | |
23 // that module's exports object. | |
24 // - requireNative, a function that takes the name of a registered | |
25 // NativeHandler and returns an object that contains the functions the | |
26 // NativeHandler defines. | |
27 // | |
28 // Each module in a ModuleSystem is executed at most once and its exports | |
29 // object cached. | |
30 // | |
31 // Note that a ModuleSystem must be used only in conjunction with a single | |
32 // v8::Context. | |
33 // TODO(koz): Rename this to JavaScriptModuleSystem. | |
34 class ModuleSystem : public NativeHandler { | |
35 public: | |
36 class SourceMap { | |
37 public: | |
38 virtual v8::Handle<v8::Value> GetSource(const std::string& name) = 0; | |
39 virtual bool Contains(const std::string& name) = 0; | |
40 }; | |
41 | |
42 // Enables native bindings for the duration of its lifetime. | |
43 class NativesEnabledScope { | |
44 public: | |
45 explicit NativesEnabledScope(ModuleSystem* module_system); | |
46 ~NativesEnabledScope(); | |
47 | |
48 private: | |
49 ModuleSystem* module_system_; | |
50 DISALLOW_COPY_AND_ASSIGN(NativesEnabledScope); | |
51 }; | |
52 | |
53 // |source_map| is a weak pointer. | |
54 explicit ModuleSystem(v8::Handle<v8::Context> context, SourceMap* source_map); | |
55 virtual ~ModuleSystem(); | |
56 | |
57 // Returns true if the current context has a ModuleSystem installed in it. | |
58 static bool IsPresentInCurrentContext(); | |
59 | |
60 // Dumps the debug info from |try_catch| to LOG(ERROR). | |
61 static void DumpException(const v8::TryCatch& try_catch); | |
62 | |
63 // Require the specified module. This is the equivalent of calling | |
64 // require('module_name') from the loaded JS files. | |
65 void Require(const std::string& module_name); | |
66 v8::Handle<v8::Value> Require(const v8::Arguments& args); | |
67 v8::Handle<v8::Value> RequireForJs(const v8::Arguments& args); | |
68 v8::Handle<v8::Value> RequireForJsInner(v8::Handle<v8::String> module_name); | |
69 | |
70 // Register |native_handler| as a potential target for requireNative(), so | |
71 // calls to requireNative(|name|) from JS will return a new object created by | |
72 // |native_handler|. | |
73 void RegisterNativeHandler(const std::string& name, | |
74 scoped_ptr<NativeHandler> native_handler); | |
75 | |
76 // Causes requireNative(|name|) to look for its module in |source_map_| | |
77 // instead of using a registered native handler. This can be used in unit | |
78 // tests to mock out native modules. | |
79 void OverrideNativeHandler(const std::string& name); | |
80 | |
81 // Executes |code| in the current context with |name| as the filename. | |
82 void RunString(const std::string& code, const std::string& name); | |
83 | |
84 // Retrieves the lazily defined field specified by |property|. | |
85 static v8::Handle<v8::Value> LazyFieldGetter(v8::Local<v8::String> property, | |
86 const v8::AccessorInfo& info); | |
87 | |
88 // Make |object|.|field| lazily evaluate to the result of | |
89 // require(|module_name|)[|module_field|]. | |
90 void SetLazyField(v8::Handle<v8::Object> object, | |
91 const std::string& field, | |
92 const std::string& module_name, | |
93 const std::string& module_field); | |
94 | |
95 private: | |
96 typedef std::map<std::string, linked_ptr<NativeHandler> > NativeHandlerMap; | |
97 | |
98 // Ensure that require_ has been evaluated from require.js. | |
99 void EnsureRequireLoaded(); | |
100 | |
101 // Run |code| in the current context with the name |name| used for stack | |
102 // traces. | |
103 v8::Handle<v8::Value> RunString(v8::Handle<v8::String> code, | |
104 v8::Handle<v8::String> name); | |
105 | |
106 // Return the named source file stored in the source map. | |
107 // |args[0]| - the name of a source file in source_map_. | |
108 v8::Handle<v8::Value> GetSource(v8::Handle<v8::String> source_name); | |
109 | |
110 // Return an object that contains the native methods defined by the named | |
111 // NativeHandler. | |
112 // |args[0]| - the name of a native handler object. | |
113 v8::Handle<v8::Value> GetNative(const v8::Arguments& args); | |
114 | |
115 // Wraps |source| in a (function(require, requireNative, exports) {...}). | |
116 v8::Handle<v8::String> WrapSource(v8::Handle<v8::String> source); | |
117 | |
118 // Throws an exception in the calling JS context. | |
119 v8::Handle<v8::Value> ThrowException(const std::string& message); | |
120 | |
121 // The context that this ModuleSystem is for. | |
122 v8::Persistent<v8::Context> context_; | |
123 | |
124 // A map from module names to the JS source for that module. GetSource() | |
125 // performs a lookup on this map. | |
126 SourceMap* source_map_; | |
127 | |
128 // A map from native handler names to native handlers. | |
129 NativeHandlerMap native_handler_map_; | |
130 | |
131 // When 0, natives are disabled, otherwise indicates how many callers have | |
132 // pinned natives as enabled. | |
133 int natives_enabled_; | |
134 | |
135 std::set<std::string> overridden_native_handlers_; | |
136 | |
137 DISALLOW_COPY_AND_ASSIGN(ModuleSystem); | |
138 }; | |
139 | |
140 #endif // CHROME_RENDERER_MODULE_SYSTEM_H_ | |
OLD | NEW |