| 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/binding_generating_native_handler.h" | 5 #include "extensions/renderer/binding_generating_native_handler.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/metrics/histogram_macros.h" | 8 #include "base/metrics/histogram_macros.h" |
| 9 #include "base/timer/elapsed_timer.h" | 9 #include "base/timer/elapsed_timer.h" |
| 10 #include "extensions/renderer/script_context.h" | 10 #include "extensions/renderer/script_context.h" |
| 11 #include "extensions/renderer/v8_helpers.h" | 11 #include "extensions/renderer/v8_helpers.h" |
| 12 #include "gin/data_object_builder.h" |
| 12 | 13 |
| 13 namespace extensions { | 14 namespace extensions { |
| 14 | 15 |
| 15 using namespace v8_helpers; | 16 using namespace v8_helpers; |
| 16 | 17 |
| 17 BindingGeneratingNativeHandler::BindingGeneratingNativeHandler( | 18 BindingGeneratingNativeHandler::BindingGeneratingNativeHandler( |
| 18 ScriptContext* context, | 19 ScriptContext* context, |
| 19 const std::string& api_name, | 20 const std::string& api_name, |
| 20 const std::string& bind_to) | 21 const std::string& bind_to) |
| 21 : context_(context), api_name_(api_name), bind_to_(bind_to) {} | 22 : context_(context), api_name_(api_name), bind_to_(bind_to) {} |
| 22 | 23 |
| 23 v8::Local<v8::Object> BindingGeneratingNativeHandler::NewInstance() { | 24 v8::Local<v8::Object> BindingGeneratingNativeHandler::NewInstance() { |
| 24 base::ElapsedTimer timer; | 25 base::ElapsedTimer timer; |
| 25 // This long sequence of commands effectively runs the JavaScript code, | 26 // This long sequence of commands effectively runs the JavaScript code, |
| 26 // such that result[bind_to] is the compiled schema for |api_name|: | 27 // such that result[bind_to] is the compiled schema for |api_name|: |
| 27 // | 28 // |
| 28 // var result = {}; | 29 // var result = {}; |
| 29 // result[bind_to] = require('binding').Binding.create(api_name).generate(); | 30 // result[bind_to] = require('binding').Binding.create(api_name).generate(); |
| 30 // return result; | 31 // return result; |
| 31 // | 32 // |
| 32 // Unfortunately using the v8 APIs makes that quite verbose. | 33 // Unfortunately using the v8 APIs makes that quite verbose. |
| 33 // Each stage is marked with the code it executes. | 34 // Each stage is marked with the code it executes. |
| 34 v8::Isolate* isolate = context_->isolate(); | 35 v8::Isolate* isolate = context_->isolate(); |
| 35 v8::EscapableHandleScope scope(isolate); | 36 v8::EscapableHandleScope scope(isolate); |
| 36 | 37 |
| 37 // Convert |api_name| and |bind_to| into their v8::Strings to pass | 38 // Convert |api_name| and |bind_to| into their v8::Strings to pass |
| 38 // through the v8 APIs. | 39 // through the v8 APIs. |
| 39 v8::Local<v8::String> v8_api_name; | 40 v8::Local<v8::String> v8_api_name; |
| 40 v8::Local<v8::String> v8_bind_to; | 41 if (!ToV8String(isolate, api_name_, &v8_api_name)) { |
| 41 if (!ToV8String(isolate, api_name_, &v8_api_name) || | |
| 42 !ToV8String(isolate, bind_to_, &v8_bind_to)) { | |
| 43 NOTREACHED(); | 42 NOTREACHED(); |
| 44 return v8::Local<v8::Object>(); | 43 return v8::Local<v8::Object>(); |
| 45 } | 44 } |
| 46 | 45 |
| 47 v8::Local<v8::Context> v8_context = context_->v8_context(); | 46 v8::Local<v8::Context> v8_context = context_->v8_context(); |
| 48 | 47 |
| 49 // require('binding'); | 48 // require('binding'); |
| 50 v8::Local<v8::Object> binding_module; | 49 v8::Local<v8::Object> binding_module; |
| 51 if (!context_->module_system()->Require("binding").ToLocal(&binding_module)) { | 50 if (!context_->module_system()->Require("binding").ToLocal(&binding_module)) { |
| 52 NOTREACHED(); | 51 NOTREACHED(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 // require('binding').Binding.create(api_name).generate; | 86 // require('binding').Binding.create(api_name).generate; |
| 88 v8::Local<v8::Value> generate_value; | 87 v8::Local<v8::Value> generate_value; |
| 89 if (!GetProperty(v8_context, binding_instance, "generate", &generate_value) || | 88 if (!GetProperty(v8_context, binding_instance, "generate", &generate_value) || |
| 90 !generate_value->IsFunction()) { | 89 !generate_value->IsFunction()) { |
| 91 NOTREACHED(); | 90 NOTREACHED(); |
| 92 return v8::Local<v8::Object>(); | 91 return v8::Local<v8::Object>(); |
| 93 } | 92 } |
| 94 v8::Local<v8::Function> generate = generate_value.As<v8::Function>(); | 93 v8::Local<v8::Function> generate = generate_value.As<v8::Function>(); |
| 95 | 94 |
| 96 // require('binding').Binding.create(api_name).generate(); | 95 // require('binding').Binding.create(api_name).generate(); |
| 97 v8::Local<v8::Object> object = v8::Object::New(isolate); | |
| 98 v8::Local<v8::Value> compiled_schema; | 96 v8::Local<v8::Value> compiled_schema; |
| 99 if (!CallFunction(v8_context, generate, binding_instance, 0, nullptr, | 97 if (!CallFunction(v8_context, generate, binding_instance, 0, nullptr, |
| 100 &compiled_schema)) { | 98 &compiled_schema)) { |
| 101 NOTREACHED(); | 99 NOTREACHED(); |
| 102 return v8::Local<v8::Object>(); | 100 return v8::Local<v8::Object>(); |
| 103 } | 101 } |
| 104 | 102 |
| 105 // var result = {}; | 103 // var result = {}; |
| 106 // result[bind_to] = ...; | 104 // result[bind_to] = ...; |
| 107 if (!SetProperty(v8_context, object, v8_bind_to, compiled_schema)) { | 105 v8::Local<v8::Object> object = |
| 108 NOTREACHED(); | 106 gin::DataObjectBuilder(isolate).Set(bind_to_, compiled_schema).Build(); |
| 109 return v8::Local<v8::Object>(); | |
| 110 } | |
| 111 | 107 |
| 112 // Log UMA with microsecond accuracy*; maxes at 10 seconds. | 108 // Log UMA with microsecond accuracy*; maxes at 10 seconds. |
| 113 // *Obviously, limited by our TimeTicks implementation, but as close as | 109 // *Obviously, limited by our TimeTicks implementation, but as close as |
| 114 // possible. | 110 // possible. |
| 115 UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.ApiBindingObjectGenerationTime", | 111 UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.ApiBindingObjectGenerationTime", |
| 116 timer.Elapsed().InMicroseconds(), | 112 timer.Elapsed().InMicroseconds(), |
| 117 1, 10000000, 100); | 113 1, 10000000, 100); |
| 118 // return result; | 114 // return result; |
| 119 return scope.Escape(object); | 115 return scope.Escape(object); |
| 120 } | 116 } |
| 121 | 117 |
| 122 } // namespace extensions | 118 } // namespace extensions |
| OLD | NEW |