#ifndef V8Proxy_h
#define V8Proxy_h
#include "PlatformSupport.h"
#include "SharedPersistent.h"
#include "StatsCounter.h"
#include "V8AbstractEventListener.h"
#include "V8DOMWindowShell.h"
#include "V8DOMWrapper.h"
#include "V8GCController.h"
#include "V8Utilities.h"
#include "WrapperTypeInfo.h"
#include <v8.h>
#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h> // so generated bindings don't have to
#include <wtf/Vector.h>
#include <wtf/text/TextPosition.h>
#if defined(ENABLE_DOM_STATS_COUNTERS) && PLATFORM(CHROMIUM)
#define INC_STATS(name) StatsCounter::incrementStatsCounter(name)
#else
#define INC_STATS(name)
#endif
namespace WebCore {
class CachedScript;
class DOMWindow;
class Frame;
class Node;
class ScriptExecutionContext;
class ScriptSourceCode;
class SecurityOrigin;
class V8BindingPerContextData;
class V8EventListener;
class V8IsolatedContext;
class WorldContextHandle;
struct BatchedAttribute {
const char* const name;
v8::AccessorGetter getter;
v8::AccessorSetter setter;
WrapperTypeInfo* data;
v8::AccessControl settings;
v8::PropertyAttribute attribute;
bool onProto;
};
void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedAttribute*, size_t attributeCount);
inline void configureAttribute(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute& attribute)
{
(attribute.onProto ? proto : instance)->SetAccessor(v8::String::New(attribute.name),
attribute.getter,
attribute.setter,
v8::External::Wrap(attribute.data),
attribute.settings,
attribute.attribute);
}
struct BatchedConstant {
const char* const name;
int value;
};
void batchConfigureConstants(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedConstant*, size_t constantCount);
struct BatchedCallback {
const char* const name;
v8::InvocationCallback callback;
};
void batchConfigureCallbacks(v8::Handle<v8::ObjectTemplate>,
v8::Handle<v8::Signature>,
v8::PropertyAttribute,
const BatchedCallback*,
size_t callbackCount);
const int kMaxRecursionDepth = 22;
typedef WTF::Vector<v8::Extension*> V8Extensions;
class V8Proxy {
public:
enum ErrorType {
RangeError,
ReferenceError,
SyntaxError,
TypeError,
GeneralError
};
explicit V8Proxy(Frame*);
~V8Proxy();
Frame* frame() { return m_frame; }
void clearForNavigation();
void clearForClose();
void finishedWithEvent(Event*) { }
void evaluateInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup, WTF::Vector<v8::Local<v8::Value> >* result);
void setIsolatedWorldSecurityOrigin(int worldID, PassRefPtr<SecurityOrigin>);
v8::Local<v8::Value> evaluate(const ScriptSourceCode&, Node*);
v8::Local<v8::Value> runScript(v8::Handle<v8::Script>);
v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
static v8::Local<v8::Value> instrumentedCallFunction(Frame*, v8::Handle<v8::Function>, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]);
v8::Local<v8::Value> newInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
static DOMWindow* retrieveWindow(v8::Handle<v8::Context>);
static V8Proxy* retrieve();
static V8Proxy* retrieve(Frame*);
static V8Proxy* retrieve(ScriptExecutionContext*);
static Frame* retrieveFrame(v8::Handle<v8::Context>);
static V8BindingPerContextData* retrievePerContextData(Frame*);
static Frame* retrieveFrameForEnteredContext();
static Frame* retrieveFrameForCurrentContext();
static DOMWindow* retrieveWindowForCallingContext();
static Frame* retrieveFrameForCallingContext();
static v8::Local<v8::Context> context(Frame*);
static v8::Local<v8::Context> mainWorldContext(Frame*);
static v8::Local<v8::Context> currentContext();
static bool handleOutOfMemory();
static v8::Handle<v8::Value> checkNewLegal(const v8::Arguments&);
static v8::Handle<v8::Script> compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, v8::ScriptData* = 0);
static void setDOMException(int exceptionCode, v8::Isolate*);
static v8::Handle<v8::Value> throwError(ErrorType, const char* message, v8::Isolate* = 0);
static v8::Handle<v8::Value> throwTypeError();
static v8::Handle<v8::Value> throwNotEnoughArgumentsError();
v8::Local<v8::Context> context();
v8::Local<v8::Context> mainWorldContext();
bool matchesCurrentContext();
V8DOMWindowShell* windowShell() const { return m_windowShell.get(); }
bool setContextDebugId(int id);
static int contextDebugId(v8::Handle<v8::Context>);
static void registerExtension(v8::Extension*);
static void registerExtensionWithV8(v8::Extension*);
static bool registeredExtensionWithV8(v8::Extension*);
static const V8Extensions& extensions();
static void reportUnsafeAccessTo(Frame* target);
private:
void resetIsolatedWorlds();
PassOwnPtr<v8::ScriptData> precompileScript(v8::Handle<v8::String>, CachedScript*);
static const char* rangeExceptionName(int exceptionCode);
static const char* eventExceptionName(int exceptionCode);
static const char* xmlHttpRequestExceptionName(int exceptionCode);
static const char* domExceptionName(int exceptionCode);
static const char* xpathExceptionName(int exceptionCode);
#if ENABLE(SVG)
static const char* svgExceptionName(int exceptionCode);
#endif
#if ENABLE(SQL_DATABASE)
static const char* sqlExceptionName(int exceptionCode);
#endif
Frame* m_frame;
RefPtr<V8DOMWindowShell> m_windowShell;
static V8Extensions m_extensions;
typedef HashMap<int, V8IsolatedContext*> IsolatedWorldMap;
IsolatedWorldMap m_isolatedWorlds;
typedef HashMap<int, RefPtr<SecurityOrigin> > IsolatedWorldSecurityOriginMap;
IsolatedWorldSecurityOriginMap m_isolatedWorldSecurityOrigins;
};
v8::Local<v8::Context> toV8Context(ScriptExecutionContext*, const WorldContextHandle& worldContext);
inline static v8::Local<v8::Object> notHandledByInterceptor()
{
return v8::Local<v8::Object>();
}
inline static v8::Local<v8::Boolean> deletionNotHandledByInterceptor()
{
return v8::Local<v8::Boolean>();
}
inline v8::Handle<v8::Primitive> throwError(const char* message, v8::Isolate* isolate = 0)
{
if (!v8::V8::IsExecutionTerminating())
V8Proxy::throwError(V8Proxy::TypeError, message, isolate);
return v8::Undefined();
}
inline v8::Handle<v8::Primitive> throwError(const char* message, V8Proxy::ErrorType type, v8::Isolate* isolate = 0)
{
if (!v8::V8::IsExecutionTerminating())
V8Proxy::throwError(type, message, isolate);
return v8::Undefined();
}
inline v8::Handle<v8::Primitive> throwError(ExceptionCode ec, v8::Isolate* isolate = 0)
{
if (!v8::V8::IsExecutionTerminating())
V8Proxy::setDOMException(ec, isolate);
return v8::Undefined();
}
inline v8::Handle<v8::Primitive> throwError(v8::Local<v8::Value> exception, v8::Isolate* isolate = 0)
{
if (!v8::V8::IsExecutionTerminating())
v8::ThrowException(exception);
return v8::Undefined();
}
enum IndependentMode {
MarkIndependent,
DoNotMarkIndependent
};
}
#endif // V8Proxy_h