preload_utils.cc 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright (c) 2016 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/renderer/preload_utils.h"
  5. #include "base/process/process.h"
  6. #include "shell/common/gin_helper/arguments.h"
  7. #include "shell/common/gin_helper/dictionary.h"
  8. #include "shell/common/node_includes.h"
  9. #include "v8/include/v8-context.h"
  10. namespace electron::preload_utils {
  11. namespace {
  12. constexpr std::string_view kBindingCacheKey = "native-binding-cache";
  13. v8::Local<v8::Object> GetBindingCache(v8::Isolate* isolate) {
  14. auto context = isolate->GetCurrentContext();
  15. gin_helper::Dictionary global(isolate, context->Global());
  16. v8::Local<v8::Value> cache;
  17. if (!global.GetHidden(kBindingCacheKey, &cache)) {
  18. cache = v8::Object::New(isolate);
  19. global.SetHidden(kBindingCacheKey, cache);
  20. }
  21. return cache->ToObject(context).ToLocalChecked();
  22. }
  23. } // namespace
  24. // adapted from node.cc
  25. v8::Local<v8::Value> GetBinding(v8::Isolate* isolate,
  26. v8::Local<v8::String> key,
  27. gin_helper::Arguments* margs) {
  28. v8::Local<v8::Object> exports;
  29. std::string binding_key = gin::V8ToString(isolate, key);
  30. gin_helper::Dictionary cache(isolate, GetBindingCache(isolate));
  31. if (cache.Get(binding_key, &exports)) {
  32. return exports;
  33. }
  34. auto* mod = node::binding::get_linked_module(binding_key.c_str());
  35. if (!mod) {
  36. char errmsg[1024];
  37. snprintf(errmsg, sizeof(errmsg), "No such binding: %s",
  38. binding_key.c_str());
  39. margs->ThrowError(errmsg);
  40. return exports;
  41. }
  42. exports = v8::Object::New(isolate);
  43. DCHECK_EQ(mod->nm_register_func, nullptr);
  44. DCHECK_NE(mod->nm_context_register_func, nullptr);
  45. mod->nm_context_register_func(exports, v8::Null(isolate),
  46. isolate->GetCurrentContext(), mod->nm_priv);
  47. cache.Set(binding_key, exports);
  48. return exports;
  49. }
  50. v8::Local<v8::Value> CreatePreloadScript(v8::Isolate* isolate,
  51. v8::Local<v8::String> source) {
  52. auto context = isolate->GetCurrentContext();
  53. auto maybe_script = v8::Script::Compile(context, source);
  54. v8::Local<v8::Script> script;
  55. if (!maybe_script.ToLocal(&script))
  56. return {};
  57. return script->Run(context).ToLocalChecked();
  58. }
  59. double Uptime() {
  60. return (base::Time::Now() - base::Process::Current().CreationTime())
  61. .InSecondsF();
  62. }
  63. } // namespace electron::preload_utils