| OLD | NEW | 
|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "extensions/renderer/module_system.h" | 5 #include "extensions/renderer/module_system.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" | 
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" | 
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" | 
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" | 
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" | 
| 13 #include "content/public/renderer/render_view.h" | 13 #include "content/public/renderer/render_view.h" | 
| 14 #include "extensions/common/extension_messages.h" | 14 #include "extensions/common/extension_messages.h" | 
| 15 #include "extensions/common/extensions_client.h" | 15 #include "extensions/common/extensions_client.h" | 
| 16 #include "extensions/renderer/console.h" | 16 #include "extensions/renderer/console.h" | 
| 17 #include "extensions/renderer/safe_builtins.h" | 17 #include "extensions/renderer/safe_builtins.h" | 
| 18 #include "extensions/renderer/script_context.h" | 18 #include "extensions/renderer/script_context.h" | 
|  | 19 #include "gin/modules/module_registry.h" | 
| 19 #include "third_party/WebKit/public/web/WebFrame.h" | 20 #include "third_party/WebKit/public/web/WebFrame.h" | 
| 20 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" | 21 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" | 
| 21 | 22 | 
| 22 namespace extensions { | 23 namespace extensions { | 
| 23 | 24 | 
| 24 namespace { | 25 namespace { | 
| 25 | 26 | 
| 26 const char* kModuleSystem = "module_system"; | 27 const char* kModuleSystem = "module_system"; | 
| 27 const char* kModuleName = "module_name"; | 28 const char* kModuleName = "module_name"; | 
| 28 const char* kModuleField = "module_field"; | 29 const char* kModuleField = "module_field"; | 
| 29 const char* kModulesField = "modules"; |  | 
| 30 | 30 | 
| 31 // Logs a fatal error for the calling context, with some added metadata about | 31 // Logs a fatal error for the calling context, with some added metadata about | 
| 32 // the context: | 32 // the context: | 
| 33 //  - Its type (blessed, unblessed, etc). | 33 //  - Its type (blessed, unblessed, etc). | 
| 34 //  - Whether it's valid. | 34 //  - Whether it's valid. | 
| 35 //  - The extension ID, if one exists. | 35 //  - The extension ID, if one exists. | 
| 36 // | 36 // | 
| 37 // This will only actual be fatal in in dev/canary, since in too many cases | 37 // This will only actual be fatal in in dev/canary, since in too many cases | 
| 38 // we're at the mercy of the extension or web page's environment. They can mess | 38 // we're at the mercy of the extension or web page's environment. They can mess | 
| 39 // up our JS in unexpected ways. Hopefully dev/canary channel will pick up such | 39 // up our JS in unexpected ways. Hopefully dev/canary channel will pick up such | 
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 126       "require", | 126       "require", | 
| 127       base::Bind(&ModuleSystem::RequireForJs, base::Unretained(this))); | 127       base::Bind(&ModuleSystem::RequireForJs, base::Unretained(this))); | 
| 128   RouteFunction( | 128   RouteFunction( | 
| 129       "requireNative", | 129       "requireNative", | 
| 130       base::Bind(&ModuleSystem::RequireNative, base::Unretained(this))); | 130       base::Bind(&ModuleSystem::RequireNative, base::Unretained(this))); | 
| 131   RouteFunction("privates", | 131   RouteFunction("privates", | 
| 132                 base::Bind(&ModuleSystem::Private, base::Unretained(this))); | 132                 base::Bind(&ModuleSystem::Private, base::Unretained(this))); | 
| 133 | 133 | 
| 134   v8::Handle<v8::Object> global(context->v8_context()->Global()); | 134   v8::Handle<v8::Object> global(context->v8_context()->Global()); | 
| 135   v8::Isolate* isolate = context->isolate(); | 135   v8::Isolate* isolate = context->isolate(); | 
| 136   global->SetHiddenValue(v8::String::NewFromUtf8(isolate, kModulesField), |  | 
| 137                          v8::Object::New(isolate)); |  | 
| 138   global->SetHiddenValue(v8::String::NewFromUtf8(isolate, kModuleSystem), | 136   global->SetHiddenValue(v8::String::NewFromUtf8(isolate, kModuleSystem), | 
| 139                          v8::External::New(isolate, this)); | 137                          v8::External::New(isolate, this)); | 
|  | 138 | 
|  | 139   gin::ModuleRegistry* registry = | 
|  | 140       gin::ModuleRegistry::From(context->v8_context()); | 
|  | 141   DCHECK(registry); | 
|  | 142   registry->AddObserver(this); | 
|  | 143   registry->AddBuiltinModule( | 
|  | 144       GetIsolate(), "array", context->safe_builtins()->GetArray()); | 
|  | 145   registry->AddBuiltinModule(GetIsolate(), "console", console::AsV8Object()); | 
|  | 146   registry->AddBuiltinModule( | 
|  | 147       GetIsolate(), "function", context->safe_builtins()->GetFunction()); | 
|  | 148   registry->AddBuiltinModule( | 
|  | 149       GetIsolate(), "json", context->safe_builtins()->GetJSON()); | 
|  | 150   registry->AddBuiltinModule( | 
|  | 151       GetIsolate(), "object", context->safe_builtins()->GetObjekt()); | 
|  | 152   registry->AddBuiltinModule( | 
|  | 153       GetIsolate(), "regexp", context->safe_builtins()->GetRegExp()); | 
|  | 154   registry->AddBuiltinModule( | 
|  | 155       GetIsolate(), "string", context->safe_builtins()->GetString()); | 
|  | 156   v8::Handle<v8::Object> natives(NewInstance()); | 
|  | 157   registry->AddBuiltinModule( | 
|  | 158       GetIsolate(), | 
|  | 159       "require", | 
|  | 160       natives->Get(v8::String::NewFromUtf8( | 
|  | 161           GetIsolate(), "require", v8::String::kInternalizedString))); | 
|  | 162   registry->AddBuiltinModule( | 
|  | 163       GetIsolate(), | 
|  | 164       "requireNative", | 
|  | 165       natives->Get(v8::String::NewFromUtf8( | 
|  | 166           GetIsolate(), "requireNative", v8::String::kInternalizedString))); | 
|  | 167   registry->AddBuiltinModule( | 
|  | 168       GetIsolate(), | 
|  | 169       "privates", | 
|  | 170       natives->Get(v8::String::NewFromUtf8( | 
|  | 171           GetIsolate(), "privates", v8::String::kInternalizedString))); | 
|  | 172 | 
|  | 173   modules_supporting_amd_.insert("app.runtime"); | 
|  | 174   modules_supporting_amd_.insert("entryIdManager"); | 
| 140 } | 175 } | 
| 141 | 176 | 
| 142 ModuleSystem::~ModuleSystem() { Invalidate(); } | 177 ModuleSystem::~ModuleSystem() { Invalidate(); } | 
| 143 | 178 | 
| 144 void ModuleSystem::Invalidate() { | 179 void ModuleSystem::Invalidate() { | 
| 145   if (!is_valid()) | 180   if (!is_valid()) | 
| 146     return; | 181     return; | 
| 147 | 182 | 
| 148   // Clear the module system properties from the global context. It's polite, | 183   // Clear the module system properties from the global context. It's polite, | 
| 149   // and we use this as a signal in lazy handlers that we no longer exist. | 184   // and we use this as a signal in lazy handlers that we no longer exist. | 
| 150   { | 185   { | 
| 151     v8::HandleScope scope(GetIsolate()); | 186     v8::HandleScope scope(GetIsolate()); | 
| 152     v8::Handle<v8::Object> global = context()->v8_context()->Global(); | 187     v8::Handle<v8::Object> global = context()->v8_context()->Global(); | 
| 153     global->DeleteHiddenValue( | 188     global->DeleteHiddenValue( | 
| 154         v8::String::NewFromUtf8(GetIsolate(), kModulesField)); |  | 
| 155     global->DeleteHiddenValue( |  | 
| 156         v8::String::NewFromUtf8(GetIsolate(), kModuleSystem)); | 189         v8::String::NewFromUtf8(GetIsolate(), kModuleSystem)); | 
| 157   } | 190   } | 
| 158 | 191 | 
| 159   // Invalidate all of the successfully required handlers we own. | 192   // Invalidate all of the successfully required handlers we own. | 
| 160   for (NativeHandlerMap::iterator it = native_handler_map_.begin(); | 193   for (NativeHandlerMap::iterator it = native_handler_map_.begin(); | 
| 161        it != native_handler_map_.end(); | 194        it != native_handler_map_.end(); | 
| 162        ++it) { | 195        ++it) { | 
| 163     it->second->Invalidate(); | 196     it->second->Invalidate(); | 
| 164   } | 197   } | 
| 165 | 198 | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 191     const v8::FunctionCallbackInfo<v8::Value>& args) { | 224     const v8::FunctionCallbackInfo<v8::Value>& args) { | 
| 192   v8::Handle<v8::String> module_name = args[0]->ToString(); | 225   v8::Handle<v8::String> module_name = args[0]->ToString(); | 
| 193   args.GetReturnValue().Set(RequireForJsInner(module_name)); | 226   args.GetReturnValue().Set(RequireForJsInner(module_name)); | 
| 194 } | 227 } | 
| 195 | 228 | 
| 196 v8::Local<v8::Value> ModuleSystem::RequireForJsInner( | 229 v8::Local<v8::Value> ModuleSystem::RequireForJsInner( | 
| 197     v8::Handle<v8::String> module_name) { | 230     v8::Handle<v8::String> module_name) { | 
| 198   v8::EscapableHandleScope handle_scope(GetIsolate()); | 231   v8::EscapableHandleScope handle_scope(GetIsolate()); | 
| 199   v8::Context::Scope context_scope(context()->v8_context()); | 232   v8::Context::Scope context_scope(context()->v8_context()); | 
| 200 | 233 | 
| 201   v8::Handle<v8::Object> global(context()->v8_context()->Global()); | 234   std::string module_name_str = | 
| 202 | 235       std::string(*v8::String::Utf8Value(module_name)); | 
| 203   // The module system might have been deleted. This can happen if a different | 236   gin::ModuleRegistry* registry = | 
| 204   // context keeps a reference to us, but our frame is destroyed (e.g. | 237       gin::ModuleRegistry::From(context()->v8_context()); | 
| 205   // background page keeps reference to chrome object in a closed popup). | 238   if (!registry) { | 
| 206   v8::Handle<v8::Value> modules_value = global->GetHiddenValue( | 239     return handle_scope.Escape( | 
| 207       v8::String::NewFromUtf8(GetIsolate(), kModulesField)); | 240         v8::Local<v8::Primitive>(v8::Undefined(GetIsolate()))); | 
| 208   if (modules_value.IsEmpty() || modules_value->IsUndefined()) { |  | 
| 209     Warn(GetIsolate(), "Extension view no longer exists"); |  | 
| 210     return v8::Undefined(GetIsolate()); |  | 
| 211   } | 241   } | 
| 212 | 242 | 
| 213   v8::Handle<v8::Object> modules(v8::Handle<v8::Object>::Cast(modules_value)); | 243   if (registry->available_modules().count(module_name_str) == 0 && | 
| 214   v8::Local<v8::Value> exports(modules->Get(module_name)); | 244       !LoadModule(module_name_str)) { | 
| 215   if (!exports->IsUndefined()) | 245     return handle_scope.Escape( | 
| 216     return handle_scope.Escape(exports); | 246         v8::Local<v8::Primitive>(v8::Undefined(GetIsolate()))); | 
|  | 247   } | 
|  | 248   return handle_scope.Escape( | 
|  | 249       v8::Local<v8::Value>(registry->GetModule(GetIsolate(), module_name_str))); | 
|  | 250 } | 
| 217 | 251 | 
| 218   std::string module_name_str = *v8::String::Utf8Value(module_name); | 252 bool ModuleSystem::LoadModule(const std::string& module_name) { | 
| 219   v8::Handle<v8::Value> source(GetSource(module_name_str)); | 253   if (failed_module_loads_.count(module_name) != 0) | 
|  | 254     return false; | 
|  | 255 | 
|  | 256   gin::ModuleRegistry* registry = | 
|  | 257       gin::ModuleRegistry::From(context()->v8_context()); | 
|  | 258   DCHECK_EQ(0u, registry->available_modules().count(module_name)); | 
|  | 259   v8::HandleScope handle_scope(GetIsolate()); | 
|  | 260   v8::Context::Scope context_scope(context()->v8_context()); | 
|  | 261 | 
|  | 262   if (LoadNative(module_name)) | 
|  | 263     return true; | 
|  | 264 | 
|  | 265   v8::Handle<v8::Value> source(GetSource(module_name)); | 
| 220   if (source.IsEmpty() || source->IsUndefined()) { | 266   if (source.IsEmpty() || source->IsUndefined()) { | 
| 221     Fatal(context_, "No source for require(" + module_name_str + ")"); | 267     Fatal(context_, "No source for module " + module_name); | 
| 222     return v8::Undefined(GetIsolate()); | 268     return false; | 
| 223   } | 269   } | 
| 224   v8::Handle<v8::String> wrapped_source( | 270   v8::Handle<v8::String> wrapped_source( | 
| 225       WrapSource(v8::Handle<v8::String>::Cast(source))); | 271       WrapSource(v8::Handle<v8::String>::Cast(source), module_name)); | 
| 226   // Modules are wrapped in (function(){...}) so they always return functions. | 272   // Modules are wrapped in (function(){...}) so they always return functions. | 
| 227   v8::Handle<v8::Value> func_as_value = RunString(wrapped_source, module_name); | 273   v8::Handle<v8::String> module_name_js( | 
|  | 274       v8::String::NewFromUtf8(GetIsolate(), module_name.c_str())); | 
|  | 275   v8::Handle<v8::Value> func_as_value = | 
|  | 276       RunString(wrapped_source, module_name_js); | 
| 228   if (func_as_value.IsEmpty() || func_as_value->IsUndefined()) { | 277   if (func_as_value.IsEmpty() || func_as_value->IsUndefined()) { | 
| 229     Fatal(context_, "Bad source for require(" + module_name_str + ")"); | 278     Fatal(context_, "Bad source for module " + module_name); | 
| 230     return v8::Undefined(GetIsolate()); | 279     return false; | 
| 231   } | 280   } | 
| 232 | 281 | 
| 233   v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(func_as_value); | 282   v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(func_as_value); | 
| 234 | 283 | 
| 235   exports = v8::Object::New(GetIsolate()); | 284   v8::Handle<v8::Object> define_object = v8::Object::New(GetIsolate()); | 
| 236   v8::Handle<v8::Object> natives(NewInstance()); | 285   gin::ModuleRegistry::InstallGlobals(GetIsolate(), define_object); | 
| 237   CHECK(!natives.IsEmpty());  // this can happen if v8 has issues |  | 
| 238 | 286 | 
| 239   // These must match the argument order in WrapSource. | 287   // These must match the argument order in WrapAmdSource. | 
| 240   v8::Handle<v8::Value> args[] = { | 288   v8::Handle<v8::Value> args[] = { | 
| 241       // CommonJS. | 289       define_object->Get(v8::String::NewFromUtf8(GetIsolate(), "define")), | 
| 242       natives->Get(v8::String::NewFromUtf8( | 290   }; | 
| 243           GetIsolate(), "require", v8::String::kInternalizedString)), |  | 
| 244       natives->Get(v8::String::NewFromUtf8( |  | 
| 245           GetIsolate(), "requireNative", v8::String::kInternalizedString)), |  | 
| 246       exports, |  | 
| 247       // Libraries that we magically expose to every module. |  | 
| 248       console::AsV8Object(), |  | 
| 249       natives->Get(v8::String::NewFromUtf8( |  | 
| 250           GetIsolate(), "privates", v8::String::kInternalizedString)), |  | 
| 251       // Each safe builtin. Keep in order with the arguments in WrapSource. |  | 
| 252       context_->safe_builtins()->GetArray(), |  | 
| 253       context_->safe_builtins()->GetFunction(), |  | 
| 254       context_->safe_builtins()->GetJSON(), |  | 
| 255       context_->safe_builtins()->GetObjekt(), |  | 
| 256       context_->safe_builtins()->GetRegExp(), |  | 
| 257       context_->safe_builtins()->GetString(), }; |  | 
| 258   { | 291   { | 
| 259     v8::TryCatch try_catch; | 292     v8::TryCatch try_catch; | 
| 260     try_catch.SetCaptureMessage(true); | 293     try_catch.SetCaptureMessage(true); | 
| 261     context_->CallFunction(func, arraysize(args), args); | 294     context_->CallFunction(func, arraysize(args), args); | 
| 262     if (try_catch.HasCaught()) { | 295     if (try_catch.HasCaught()) | 
| 263       HandleException(try_catch); | 296       HandleException(try_catch); | 
| 264       return v8::Undefined(GetIsolate()); |  | 
| 265     } |  | 
| 266   } | 297   } | 
| 267   modules->Set(module_name, exports); | 298   if (registry->available_modules().count(module_name) == 0) { | 
| 268   return handle_scope.Escape(exports); | 299     failed_module_loads_.insert(module_name); | 
|  | 300     return false; | 
|  | 301   } | 
|  | 302   return true; | 
|  | 303 } | 
|  | 304 | 
|  | 305 bool ModuleSystem::LoadNative(const std::string& native_name) { | 
|  | 306   if (natives_enabled_ == 0) | 
|  | 307     return false; | 
|  | 308 | 
|  | 309   v8::HandleScope scope(GetIsolate()); | 
|  | 310   gin::ModuleRegistry* registry = | 
|  | 311       gin::ModuleRegistry::From(context_->v8_context()); | 
|  | 312   if (overridden_native_handlers_.count(native_name) > 0u) | 
|  | 313     return false; | 
|  | 314 | 
|  | 315   NativeHandlerMap::iterator i = native_handler_map_.find(native_name); | 
|  | 316   if (i == native_handler_map_.end()) { | 
|  | 317     return false; | 
|  | 318   } | 
|  | 319 | 
|  | 320   registry->AddBuiltinModule( | 
|  | 321       GetIsolate(), native_name, i->second->NewInstance()); | 
|  | 322   return true; | 
|  | 323 } | 
|  | 324 | 
|  | 325 void ModuleSystem::OnDidAddPendingModule( | 
|  | 326     const std::string& id, | 
|  | 327     const std::vector<std::string>& dependencies) { | 
|  | 328   if (!source_map_->Contains(id)) | 
|  | 329     return; | 
|  | 330 | 
|  | 331   gin::ModuleRegistry* registry = | 
|  | 332       gin::ModuleRegistry::From(context_->v8_context()); | 
|  | 333   for (std::vector<std::string>::const_iterator it = dependencies.begin(); | 
|  | 334        it != dependencies.end(); | 
|  | 335        ++it) { | 
|  | 336     if (registry->available_modules().count(*it) != 0) | 
|  | 337       continue; | 
|  | 338 | 
|  | 339     if (!LoadModule(*it)) | 
|  | 340       LOG(DFATAL) << "Invalid dependency " << *it << " in module " << id; | 
|  | 341   } | 
|  | 342   gin::ModuleRegistry::From(context_->v8_context()) | 
|  | 343       ->AttemptToLoadMoreModules(GetIsolate()); | 
| 269 } | 344 } | 
| 270 | 345 | 
| 271 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( | 346 v8::Local<v8::Value> ModuleSystem::CallModuleMethod( | 
| 272     const std::string& module_name, | 347     const std::string& module_name, | 
| 273     const std::string& method_name) { | 348     const std::string& method_name) { | 
| 274   v8::HandleScope handle_scope(GetIsolate()); | 349   v8::HandleScope handle_scope(GetIsolate()); | 
| 275   v8::Handle<v8::Value> no_args; | 350   v8::Handle<v8::Value> no_args; | 
| 276   return CallModuleMethod(module_name, method_name, 0, &no_args); | 351   return CallModuleMethod(module_name, method_name, 0, &no_args); | 
| 277 } | 352 } | 
| 278 | 353 | 
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 536     // HACK: if in test throw exception so that we can test the natives-disabled | 611     // HACK: if in test throw exception so that we can test the natives-disabled | 
| 537     // logic; however, under normal circumstances, this is programmer error so | 612     // logic; however, under normal circumstances, this is programmer error so | 
| 538     // we could crash. | 613     // we could crash. | 
| 539     if (exception_handler_) { | 614     if (exception_handler_) { | 
| 540       return GetIsolate()->ThrowException( | 615       return GetIsolate()->ThrowException( | 
| 541           v8::String::NewFromUtf8(GetIsolate(), "Natives disabled")); | 616           v8::String::NewFromUtf8(GetIsolate(), "Natives disabled")); | 
| 542     } | 617     } | 
| 543     Fatal(context_, "Natives disabled for requireNative(" + native_name + ")"); | 618     Fatal(context_, "Natives disabled for requireNative(" + native_name + ")"); | 
| 544     return v8::Undefined(GetIsolate()); | 619     return v8::Undefined(GetIsolate()); | 
| 545   } | 620   } | 
|  | 621   gin::ModuleRegistry* registry = | 
|  | 622       gin::ModuleRegistry::From(context()->v8_context()); | 
|  | 623   if (!registry) | 
|  | 624     return v8::Undefined(GetIsolate()); | 
| 546 | 625 | 
| 547   if (overridden_native_handlers_.count(native_name) > 0u) { | 626   if (registry->available_modules().count(native_name) == 0 && | 
| 548     return RequireForJsInner( | 627       !LoadModule(native_name)) { | 
| 549         v8::String::NewFromUtf8(GetIsolate(), native_name.c_str())); |  | 
| 550   } |  | 
| 551 |  | 
| 552   NativeHandlerMap::iterator i = native_handler_map_.find(native_name); |  | 
| 553   if (i == native_handler_map_.end()) { |  | 
| 554     Fatal(context_, | 628     Fatal(context_, | 
| 555           "Couldn't find native for requireNative(" + native_name + ")"); | 629           "Couldn't find native for requireNative(" + native_name + ")"); | 
| 556     return v8::Undefined(GetIsolate()); | 630     return v8::Undefined(GetIsolate()); | 
| 557   } | 631   } | 
| 558   return i->second->NewInstance(); | 632   return registry->GetModule(GetIsolate(), native_name); | 
| 559 } | 633 } | 
| 560 | 634 | 
| 561 v8::Handle<v8::String> ModuleSystem::WrapSource(v8::Handle<v8::String> source) { | 635 v8::Handle<v8::String> ModuleSystem::WrapSource( | 
|  | 636     v8::Handle<v8::String> source, | 
|  | 637     const std::string& module_name) { | 
|  | 638   if (modules_supporting_amd_.count(module_name) != 0 || | 
|  | 639       module_name.find('/') != std::string::npos) { | 
|  | 640     return WrapAmdSource(source); | 
|  | 641   } | 
|  | 642 | 
| 562   v8::EscapableHandleScope handle_scope(GetIsolate()); | 643   v8::EscapableHandleScope handle_scope(GetIsolate()); | 
| 563   // Keep in order with the arguments in RequireForJsInner. | 644   v8::Handle<v8::String> left = | 
| 564   v8::Handle<v8::String> left = v8::String::NewFromUtf8( | 645       v8::String::NewFromUtf8(GetIsolate(), | 
| 565       GetIsolate(), | 646                               ("define('" + module_name + | 
| 566       "(function(require, requireNative, exports, " | 647                                "', [" | 
| 567       "console, privates," | 648                                "'require'," | 
| 568       "$Array, $Function, $JSON, $Object, $RegExp, $String) {" | 649                                "'requireNative'," | 
| 569       "'use strict';"); | 650                                "'privates'," | 
|  | 651                                "'array'," | 
|  | 652                                "'function'," | 
|  | 653                                "'json'," | 
|  | 654                                "'object'," | 
|  | 655                                "'regexp'," | 
|  | 656                                "'string'," | 
|  | 657                                "'console'," | 
|  | 658                                "], function(require, requireNative, privates, " | 
|  | 659                                "$Array, $Function, $JSON, " | 
|  | 660                                "$Object, $RegExp, $String, console) {" | 
|  | 661                                "var exports = {};").c_str()); | 
|  | 662   v8::Handle<v8::String> right = | 
|  | 663       v8::String::NewFromUtf8(GetIsolate(), "\nreturn exports;})"); | 
|  | 664   return handle_scope.Escape(v8::Local<v8::String>(WrapAmdSource( | 
|  | 665       v8::String::Concat(left, v8::String::Concat(source, right))))); | 
|  | 666 } | 
|  | 667 | 
|  | 668 v8::Handle<v8::String> ModuleSystem::WrapAmdSource( | 
|  | 669     v8::Handle<v8::String> source) { | 
|  | 670   v8::EscapableHandleScope handle_scope(GetIsolate()); | 
|  | 671   // Keep in order with the arguments in LoadModule. | 
|  | 672   v8::Handle<v8::String> left = | 
|  | 673       v8::String::NewFromUtf8(GetIsolate(), "(function(define) {'use strict';"); | 
| 570   v8::Handle<v8::String> right = v8::String::NewFromUtf8(GetIsolate(), "\n})"); | 674   v8::Handle<v8::String> right = v8::String::NewFromUtf8(GetIsolate(), "\n})"); | 
| 571   return handle_scope.Escape(v8::Local<v8::String>( | 675   return handle_scope.Escape(v8::Local<v8::String>( | 
| 572       v8::String::Concat(left, v8::String::Concat(source, right)))); | 676       v8::String::Concat(left, v8::String::Concat(source, right)))); | 
| 573 } | 677 } | 
| 574 | 678 | 
| 575 void ModuleSystem::Private(const v8::FunctionCallbackInfo<v8::Value>& args) { | 679 void ModuleSystem::Private(const v8::FunctionCallbackInfo<v8::Value>& args) { | 
| 576   CHECK_EQ(1, args.Length()); | 680   CHECK_EQ(1, args.Length()); | 
| 577   CHECK(args[0]->IsObject()); | 681   CHECK(args[0]->IsObject()); | 
| 578   v8::Local<v8::Object> obj = args[0].As<v8::Object>(); | 682   v8::Local<v8::Object> obj = args[0].As<v8::Object>(); | 
| 579   v8::Local<v8::String> privates_key = | 683   v8::Local<v8::String> privates_key = | 
| 580       v8::String::NewFromUtf8(GetIsolate(), "privates"); | 684       v8::String::NewFromUtf8(GetIsolate(), "privates"); | 
| 581   v8::Local<v8::Value> privates = obj->GetHiddenValue(privates_key); | 685   v8::Local<v8::Value> privates = obj->GetHiddenValue(privates_key); | 
| 582   if (privates.IsEmpty()) { | 686   if (privates.IsEmpty()) { | 
| 583     privates = v8::Object::New(args.GetIsolate()); | 687     privates = v8::Object::New(args.GetIsolate()); | 
| 584     obj->SetHiddenValue(privates_key, privates); | 688     obj->SetHiddenValue(privates_key, privates); | 
| 585   } | 689   } | 
| 586   args.GetReturnValue().Set(privates); | 690   args.GetReturnValue().Set(privates); | 
| 587 } | 691 } | 
| 588 | 692 | 
| 589 }  // namespace extensions | 693 }  // namespace extensions | 
| OLD | NEW | 
|---|