blob: 97b70934e53a72cd6a456372b4d128c59cf82dd2 [file] [log] [blame]
// Copyright 2014 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef COBALT_SCRIPT_GLOBAL_ENVIRONMENT_H_
#define COBALT_SCRIPT_GLOBAL_ENVIRONMENT_H_
#include <string>
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "cobalt/script/error_report.h"
#include "cobalt/script/script_value.h"
#include "cobalt/script/script_value_factory.h"
#include "cobalt/script/stack_frame.h"
#include "cobalt/script/value_handle.h"
#include "cobalt/script/wrappable.h"
namespace cobalt {
namespace script {
class EnvironmentSettings;
class JavaScriptEngine;
class SourceCode;
// Manages a handle to a JavaScript engine's global object.
class GlobalEnvironment : public base::RefCounted<GlobalEnvironment>,
public base::SupportsWeakPtr<GlobalEnvironment> {
public:
typedef base::Callback<bool(const ErrorReport& error_report)>
ReportErrorCallback;
// Create a new global object with bindings as defined for the definition of
// the GlobalInterface type. The IDL for this interface must have the
// PrimaryGlobal or Global extended attribute.
//
// Specializations of this template function are implemented in the
// generated bindings code for each JavaScript engine.
template <typename GlobalInterface>
void CreateGlobalObject(
const scoped_refptr<GlobalInterface>& global_interface,
EnvironmentSettings* environment_settings);
// Create a new global object with no bindings.
virtual void CreateGlobalObject() = 0;
// Evaluate the JavaScript source code. Returns true on success,
// false if there is an exception.
// If out_result is non-NULL, it will be set to hold the result of the script
// evaluation if the script succeeds, or an exception message if it fails.
virtual bool EvaluateScript(const scoped_refptr<SourceCode>& script_utf8,
std::string* out_result_utf8) = 0;
// Evaluate the JavaScript source code. Returns true on success,
// false if there is an exception.
// Set |out_value_handle| to be a reference to the result of the evaluation
// of the script that is owned by |owner|.
virtual bool EvaluateScript(
const scoped_refptr<SourceCode>& script_utf8,
const scoped_refptr<Wrappable>& owning_object,
base::Optional<ValueHandleHolder::Reference>* out_value_handle) = 0;
// Returns the stack trace as a vector of individual frames.
// Set |max_frames| to 0 to retrieve all available frames. Otherwise
// return at most |max_frames|.
virtual std::vector<StackFrame> GetStackTrace(int max_frames) = 0;
// Our style guide bans default arguments for virtual functions, however we
// ended up taking a dependency on them in our bindings code before it was
// caught. Instead, provide a non-virtual overload that wraps virtual
// |GetStackTrace(int)| to make everyone happy.
std::vector<StackFrame> GetStackTrace() { return GetStackTrace(0); }
// Register |traceable| as a member of the root set, i.e., an a priori
// reachable node. In a manner similar to |PreventGarbageCollection|,
// multiple calls are supported.
virtual void AddRoot(Traceable* traceable) = 0;
// Undo a registration from |AddRoot|.
virtual void RemoveRoot(Traceable* traceable) = 0;
// Disable eval() and specify the message to report in the exception.
virtual void DisableEval(const std::string& message) = 0;
// Allow eval().
virtual void EnableEval() = 0;
// Disable just-in-time compilation of JavaScript source code to native
// code. Calling this is a no-op if JIT was not enabled in the first place,
// or if the engine does not support disabling JIT.
virtual void DisableJit() = 0;
// Set a callback that will be fired whenever eval() or a Function()
// constructor is used.
virtual void SetReportEvalCallback(const base::Closure& report_eval) = 0;
// Set a callback that will be fired whenever a JavaScript error occurs.
virtual void SetReportErrorCallback(
const ReportErrorCallback& report_error) = 0;
// Dynamically bind a cpp object to the JavaScript global object with the
// supplied identifier.
// This method is useful for testing and debug purposes, as well as for
// dynamically injecting an API into a JavaScript environment.
//
// This static function must be implemented by the JavaScriptEngine
// implementation
virtual void Bind(const std::string& identifier,
const scoped_refptr<Wrappable>& impl) = 0;
// Dynamically bind a cpp object to a local JavaScript object with the
// supplied identifier.
// This method is useful for testing and debug purposes, as well as for
// dynamically injecting an API into a JavaScript environment.
//
// This static function must be implemented by the JavaScriptEngine
// implementation
virtual void BindTo(const std::string& identifier,
const scoped_refptr<Wrappable>& impl,
const std::string& local_object_name) = 0;
// Get the ScriptValueFactory for this global environment. The
// GlobalEnvironment instance retains ownership of the ScriptValueFactory and
// should live longer than any ScriptValueFactory pointer.
virtual ScriptValueFactory* script_value_factory() = 0;
class ScopedPreventGarbageCollection {
public:
ScopedPreventGarbageCollection(GlobalEnvironment* global_environment,
Wrappable* wrappable)
: global_environment(global_environment->AsWeakPtr()),
wrappable(wrappable) {
global_environment->PreventGarbageCollection(
base::WrapRefCounted(wrappable));
}
~ScopedPreventGarbageCollection() {
if (global_environment) {
global_environment->AllowGarbageCollection(wrappable);
}
}
private:
base::WeakPtr<GlobalEnvironment> global_environment;
Wrappable* wrappable;
};
protected:
// Prevent this wrappable's associated JavaScript wrapper object from being
// garbage collected. |AllowGarbageCollection| must be called some time
// afterwards, or else both the JavaScript wrapper object and Wrappable will
// leak. Note that multiple calls to |PreventGarbageCollection| *are*
// counted, in that calling (e.g.) prevent, prevent, allow on |wrappable|,
// implies that |wrappable| is still garbage collection prevented.
virtual void PreventGarbageCollection(
const scoped_refptr<Wrappable>& wrappable) = 0;
// Allow this wrappable's associated JavaScript wrapper object to be garbage
// collected.
virtual void AllowGarbageCollection(Wrappable* wrappable) = 0;
virtual ~GlobalEnvironment() {}
friend class base::RefCounted<GlobalEnvironment>;
};
} // namespace script
} // namespace cobalt
#endif // COBALT_SCRIPT_GLOBAL_ENVIRONMENT_H_