Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: chrome/renderer/module_system.cc

Issue 10879107: Move ModuleSystem and NativeHandler to extensions/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/module_system.h ('k') | chrome/renderer/module_system_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #include "chrome/renderer/module_system.h"
6
7 #include "base/bind.h"
8 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedMicrotaskSup pression.h"
9
10 namespace {
11
12 const char* kModuleSystem = "module_system";
13 const char* kModuleName = "module_name";
14 const char* kModuleField = "module_field";
15 const char* kModulesField = "modules";
16
17 } // namespace
18
19 ModuleSystem::ModuleSystem(v8::Handle<v8::Context> context,
20 SourceMap* source_map)
21 : context_(v8::Persistent<v8::Context>::New(context)),
22 source_map_(source_map),
23 natives_enabled_(0) {
24 RouteFunction("require",
25 base::Bind(&ModuleSystem::RequireForJs, base::Unretained(this)));
26 RouteFunction("requireNative",
27 base::Bind(&ModuleSystem::GetNative, base::Unretained(this)));
28
29 v8::Handle<v8::Object> global(context_->Global());
30 global->SetHiddenValue(v8::String::New(kModulesField), v8::Object::New());
31 global->SetHiddenValue(v8::String::New(kModuleSystem),
32 v8::External::New(this));
33 }
34
35 ModuleSystem::~ModuleSystem() {
36 v8::HandleScope handle_scope;
37 // Deleting this value here prevents future lazy field accesses from
38 // referencing ModuleSystem after it has been freed.
39 context_->Global()->DeleteHiddenValue(v8::String::New(kModuleSystem));
40 context_.Dispose();
41 }
42
43 ModuleSystem::NativesEnabledScope::NativesEnabledScope(
44 ModuleSystem* module_system)
45 : module_system_(module_system) {
46 module_system_->natives_enabled_++;
47 }
48
49 ModuleSystem::NativesEnabledScope::~NativesEnabledScope() {
50 module_system_->natives_enabled_--;
51 CHECK_GE(module_system_->natives_enabled_, 0);
52 }
53
54 // static
55 bool ModuleSystem::IsPresentInCurrentContext() {
56 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
57 v8::Handle<v8::Value> module_system =
58 global->GetHiddenValue(v8::String::New(kModuleSystem));
59 return !module_system.IsEmpty() && !module_system->IsUndefined();
60 }
61
62 // static
63 void ModuleSystem::DumpException(const v8::TryCatch& try_catch) {
64 v8::HandleScope handle_scope;
65
66 v8::Handle<v8::Message> message(try_catch.Message());
67 if (message.IsEmpty()) {
68 LOG(ERROR) << "try_catch has no message";
69 return;
70 }
71
72 std::string resource_name = "<unknown resource>";
73 if (!message->GetScriptResourceName().IsEmpty()) {
74 resource_name =
75 *v8::String::Utf8Value(message->GetScriptResourceName()->ToString());
76 }
77
78 std::string error_message = "<no error message>";
79 if (!message->Get().IsEmpty())
80 error_message = *v8::String::Utf8Value(message->Get());
81
82 std::string stack_trace = "<stack trace unavailable>";
83 if (!try_catch.StackTrace().IsEmpty()) {
84 v8::String::Utf8Value stack_value(try_catch.StackTrace());
85 if (*stack_value)
86 stack_trace.assign(*stack_value, stack_value.length());
87 else
88 stack_trace = "<could not convert stack trace to string>";
89 }
90
91 LOG(ERROR) << "[" << resource_name << "(" << message->GetLineNumber() << ")] "
92 << error_message
93 << "{" << stack_trace << "}";
94 }
95
96 void ModuleSystem::Require(const std::string& module_name) {
97 v8::HandleScope handle_scope;
98 RequireForJsInner(v8::String::New(module_name.c_str()));
99 }
100
101 v8::Handle<v8::Value> ModuleSystem::RequireForJs(const v8::Arguments& args) {
102 v8::HandleScope handle_scope;
103 v8::Handle<v8::String> module_name = args[0]->ToString();
104 return handle_scope.Close(RequireForJsInner(module_name));
105 }
106
107 v8::Handle<v8::Value> ModuleSystem::RequireForJsInner(
108 v8::Handle<v8::String> module_name) {
109 v8::HandleScope handle_scope;
110 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
111 v8::Handle<v8::Object> modules(v8::Handle<v8::Object>::Cast(
112 global->GetHiddenValue(v8::String::New(kModulesField))));
113 v8::Handle<v8::Value> exports(modules->Get(module_name));
114 if (!exports->IsUndefined())
115 return handle_scope.Close(exports);
116
117 v8::Handle<v8::Value> source(GetSource(module_name));
118 if (source->IsUndefined())
119 return handle_scope.Close(v8::Undefined());
120 v8::Handle<v8::String> wrapped_source(WrapSource(
121 v8::Handle<v8::String>::Cast(source)));
122 v8::Handle<v8::Function> func =
123 v8::Handle<v8::Function>::Cast(RunString(wrapped_source, module_name));
124 if (func.IsEmpty()) {
125 return ThrowException(std::string(*v8::String::AsciiValue(module_name)) +
126 ": Bad source");
127 }
128
129 exports = v8::Object::New();
130 v8::Handle<v8::Object> natives(NewInstance());
131 v8::Handle<v8::Value> args[] = {
132 natives->Get(v8::String::NewSymbol("require")),
133 natives->Get(v8::String::NewSymbol("requireNative")),
134 exports,
135 };
136 {
137 WebKit::WebScopedMicrotaskSuppression suppression;
138 v8::TryCatch try_catch;
139 try_catch.SetCaptureMessage(true);
140 func->Call(global, 3, args);
141 if (try_catch.HasCaught()) {
142 DumpException(try_catch);
143 return v8::Undefined();
144 }
145 }
146 modules->Set(module_name, exports);
147 return handle_scope.Close(exports);
148 }
149
150 void ModuleSystem::RegisterNativeHandler(const std::string& name,
151 scoped_ptr<NativeHandler> native_handler) {
152 native_handler_map_[name] =
153 linked_ptr<NativeHandler>(native_handler.release());
154 }
155
156 void ModuleSystem::OverrideNativeHandler(const std::string& name) {
157 overridden_native_handlers_.insert(name);
158 }
159
160 void ModuleSystem::RunString(const std::string& code, const std::string& name) {
161 v8::HandleScope handle_scope;
162 RunString(v8::String::New(code.c_str()), v8::String::New(name.c_str()));
163 }
164
165 // static
166 v8::Handle<v8::Value> ModuleSystem::LazyFieldGetter(
167 v8::Local<v8::String> property, const v8::AccessorInfo& info) {
168 CHECK(!info.Data().IsEmpty());
169 CHECK(info.Data()->IsObject());
170 v8::HandleScope handle_scope;
171 v8::Handle<v8::Object> parameters = v8::Handle<v8::Object>::Cast(info.Data());
172 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global());
173 v8::Handle<v8::Value> module_system_value =
174 global->GetHiddenValue(v8::String::New(kModuleSystem));
175 if (module_system_value->IsUndefined()) {
176 // ModuleSystem has been deleted.
177 return v8::Undefined();
178 }
179 ModuleSystem* module_system = static_cast<ModuleSystem*>(
180 v8::Handle<v8::External>::Cast(module_system_value)->Value());
181
182 v8::Handle<v8::Object> module;
183 {
184 NativesEnabledScope scope(module_system);
185 module = v8::Handle<v8::Object>::Cast(module_system->RequireForJsInner(
186 parameters->Get(v8::String::New(kModuleName))->ToString()));
187 }
188 if (module.IsEmpty())
189 return handle_scope.Close(v8::Handle<v8::Value>());
190
191 v8::Handle<v8::String> field =
192 parameters->Get(v8::String::New(kModuleField))->ToString();
193
194 return handle_scope.Close(module->Get(field));
195 }
196
197 void ModuleSystem::SetLazyField(v8::Handle<v8::Object> object,
198 const std::string& field,
199 const std::string& module_name,
200 const std::string& module_field) {
201 v8::HandleScope handle_scope;
202 v8::Handle<v8::Object> parameters = v8::Object::New();
203 parameters->Set(v8::String::New(kModuleName),
204 v8::String::New(module_name.c_str()));
205 parameters->Set(v8::String::New(kModuleField),
206 v8::String::New(module_field.c_str()));
207
208 object->SetAccessor(v8::String::New(field.c_str()),
209 &ModuleSystem::LazyFieldGetter,
210 NULL,
211 parameters);
212 }
213
214 v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code,
215 v8::Handle<v8::String> name) {
216 v8::HandleScope handle_scope;
217 WebKit::WebScopedMicrotaskSuppression suppression;
218 v8::Handle<v8::Value> result;
219 v8::TryCatch try_catch;
220 try_catch.SetCaptureMessage(true);
221 v8::Handle<v8::Script> script(v8::Script::New(code, name));
222 if (try_catch.HasCaught()) {
223 DumpException(try_catch);
224 return handle_scope.Close(result);
225 }
226
227 result = script->Run();
228 if (try_catch.HasCaught())
229 DumpException(try_catch);
230
231 return handle_scope.Close(result);
232 }
233
234 v8::Handle<v8::Value> ModuleSystem::GetSource(
235 v8::Handle<v8::String> source_name) {
236 v8::HandleScope handle_scope;
237 std::string module_name = *v8::String::AsciiValue(source_name);
238 if (!source_map_->Contains(module_name))
239 return v8::Undefined();
240 return handle_scope.Close(source_map_->GetSource(module_name));
241 }
242
243 v8::Handle<v8::Value> ModuleSystem::GetNative(const v8::Arguments& args) {
244 CHECK_EQ(1, args.Length());
245 if (natives_enabled_ == 0)
246 return ThrowException("Natives disabled");
247 std::string native_name = *v8::String::AsciiValue(args[0]->ToString());
248 if (overridden_native_handlers_.count(native_name) > 0u)
249 return RequireForJs(args);
250 NativeHandlerMap::iterator i = native_handler_map_.find(native_name);
251 if (i == native_handler_map_.end())
252 return v8::Undefined();
253 return i->second->NewInstance();
254 }
255
256 v8::Handle<v8::String> ModuleSystem::WrapSource(v8::Handle<v8::String> source) {
257 v8::HandleScope handle_scope;
258 v8::Handle<v8::String> left =
259 v8::String::New("(function(require, requireNative, exports) {");
260 v8::Handle<v8::String> right = v8::String::New("\n})");
261 return handle_scope.Close(
262 v8::String::Concat(left, v8::String::Concat(source, right)));
263 }
264
265 v8::Handle<v8::Value> ModuleSystem::ThrowException(const std::string& message) {
266 return v8::ThrowException(v8::String::New(message.c_str()));
267 }
OLDNEW
« no previous file with comments | « chrome/renderer/module_system.h ('k') | chrome/renderer/module_system_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698