Commit 902fd0fe authored by apavlov@chromium.org's avatar apavlov@chromium.org

Revert of Ensure DOMWrapperWorld always exists in all webkit_unit_tests...

Revert of Ensure DOMWrapperWorld always exists in all webkit_unit_tests (https://codereview.chromium.org/180743013/)

Reason for revert:
A few inspector tests are crashing:
WebCore::DOMWrapperWorld::ensureIsolatedWorld(int, int) [DOMWrapperWorld.cpp : 124 + 0x33]

Original issue's description:
> Ensure DOMWrapperWorld always exists in all webkit_unit_tests
> 
> Currently DOMWrapperWorld can be 0 in some tests. This is problematic since I want to make DOMWrapperWorld::current() callable from anywhere. Thus this CL adds DOMWrapperWorld to all webkit_unit_tests.
> 
> - It's verbose to initialize v8::HandleScope, v8::Context, v8::Context::Scope, V8PerContextData and DOMWrapperWorld in each test. So this CL adds a helper class (V8BindingTestScope) that does all the initialization work.
> 
> - This CL also fixes indentation of V8Binding.h.
> 
> BUG=341032
> NOTRY=true
> 
> Committed: https://src.chromium.org/viewvc/blink?view=rev&revision=168355

TBR=jochen@chromium.org,dcarney@chromium.org,haraken@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=341032

Review URL: https://codereview.chromium.org/183803017

git-svn-id: svn://svn.chromium.org/blink/trunk@168369 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent ba25a49a
...@@ -115,7 +115,7 @@ DOMWrapperWorld::~DOMWrapperWorld() ...@@ -115,7 +115,7 @@ DOMWrapperWorld::~DOMWrapperWorld()
#ifndef NDEBUG #ifndef NDEBUG
static bool isIsolatedWorldId(int worldId) static bool isIsolatedWorldId(int worldId)
{ {
return MainWorldId < worldId && worldId <= EmbedderWorldIdLimit; return worldId != MainWorldId && worldId != WorkerWorldId;
} }
#endif #endif
......
...@@ -51,13 +51,12 @@ enum WorldIdConstants { ...@@ -51,13 +51,12 @@ enum WorldIdConstants {
EmbedderWorldIdLimit = (1 << 29), EmbedderWorldIdLimit = (1 << 29),
ScriptPreprocessorIsolatedWorldId, ScriptPreprocessorIsolatedWorldId,
WorkerWorldId, WorkerWorldId,
TestingWorldId,
}; };
// This class represent a collection of DOM wrappers for a specific world. // This class represent a collection of DOM wrappers for a specific world.
class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
public: public:
static PassRefPtr<DOMWrapperWorld> create(int worldId = -1, int extensionGroup = -1); static PassRefPtr<DOMWrapperWorld> create(int worldId, int extensionGroup);
static const int mainWorldExtensionGroup = 0; static const int mainWorldExtensionGroup = 0;
static PassRefPtr<DOMWrapperWorld> ensureIsolatedWorld(int worldId, int extensionGroup); static PassRefPtr<DOMWrapperWorld> ensureIsolatedWorld(int worldId, int extensionGroup);
...@@ -97,7 +96,7 @@ public: ...@@ -97,7 +96,7 @@ public:
bool isMainWorld() const { return m_worldId == MainWorldId; } bool isMainWorld() const { return m_worldId == MainWorldId; }
bool isWorkerWorld() const { return m_worldId == WorkerWorldId; } bool isWorkerWorld() const { return m_worldId == WorkerWorldId; }
bool isIsolatedWorld() const { return MainWorldId < m_worldId && m_worldId <= EmbedderWorldIdLimit; } bool isIsolatedWorld() const { return !isMainWorld() && !isWorkerWorld(); }
int worldId() const { return m_worldId; } int worldId() const { return m_worldId; }
int extensionGroup() const { return m_extensionGroup; } int extensionGroup() const { return m_extensionGroup; }
......
...@@ -93,11 +93,14 @@ void checkKeyPathNumberValue(const ScriptValue& value, const String& keyPath, in ...@@ -93,11 +93,14 @@ void checkKeyPathNumberValue(const ScriptValue& value, const String& keyPath, in
class IDBKeyFromValueAndKeyPathTest : public testing::Test { class IDBKeyFromValueAndKeyPathTest : public testing::Test {
public: public:
IDBKeyFromValueAndKeyPathTest() IDBKeyFromValueAndKeyPathTest()
: m_scope(V8BindingTestScope::create(v8::Isolate::GetCurrent())) : m_handleScope(v8::Isolate::GetCurrent())
, m_scope(v8::Context::New(v8::Isolate::GetCurrent()))
{ {
} }
private: private:
OwnPtr<V8BindingTestScope> m_scope; v8::HandleScope m_handleScope;
v8::Context::Scope m_scope;
}; };
TEST_F(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyStringValue) TEST_F(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyStringValue)
......
...@@ -47,12 +47,16 @@ class ScriptPromiseResolverTest : public testing::Test { ...@@ -47,12 +47,16 @@ class ScriptPromiseResolverTest : public testing::Test {
public: public:
ScriptPromiseResolverTest() ScriptPromiseResolverTest()
: m_isolate(v8::Isolate::GetCurrent()) : m_isolate(v8::Isolate::GetCurrent())
, m_handleScope(m_isolate)
, m_context(m_isolate, v8::Context::New(m_isolate))
, m_contextScope(m_context.newLocal(m_isolate))
{ {
} }
void SetUp() void SetUp()
{ {
m_scope = V8BindingTestScope::create(m_isolate); // FIXME: Create a new world and pass it to V8PerContextData.
m_perContextData = V8PerContextData::create(m_context.newLocal(m_isolate), 0);
m_promise = ScriptPromise::createPending(); m_promise = ScriptPromise::createPending();
m_resolver = ScriptPromiseResolver::create(m_promise); m_resolver = ScriptPromiseResolver::create(m_promise);
} }
...@@ -61,7 +65,7 @@ public: ...@@ -61,7 +65,7 @@ public:
{ {
m_resolver = nullptr; m_resolver = nullptr;
m_promise.clear(); m_promise.clear();
m_scope.clear(); m_perContextData.clear();
} }
V8PromiseCustom::PromiseState state() V8PromiseCustom::PromiseState state()
...@@ -82,10 +86,12 @@ public: ...@@ -82,10 +86,12 @@ public:
protected: protected:
v8::Isolate* m_isolate; v8::Isolate* m_isolate;
v8::HandleScope m_handleScope;
ScopedPersistent<v8::Context> m_context;
v8::Context::Scope m_contextScope;
RefPtr<ScriptPromiseResolver> m_resolver; RefPtr<ScriptPromiseResolver> m_resolver;
ScriptPromise m_promise; ScriptPromise m_promise;
private: OwnPtr<V8PerContextData> m_perContextData;
OwnPtr<V8BindingTestScope> m_scope;
}; };
TEST_F(ScriptPromiseResolverTest, initialState) TEST_F(ScriptPromiseResolverTest, initialState)
......
...@@ -47,17 +47,21 @@ class ScriptPromiseTest : public testing::Test { ...@@ -47,17 +47,21 @@ class ScriptPromiseTest : public testing::Test {
public: public:
ScriptPromiseTest() ScriptPromiseTest()
: m_isolate(v8::Isolate::GetCurrent()) : m_isolate(v8::Isolate::GetCurrent())
, m_handleScope(m_isolate)
, m_context(m_isolate, v8::Context::New(m_isolate))
, m_contextScope(m_context.newLocal(m_isolate))
{ {
} }
void SetUp() void SetUp()
{ {
m_scope = V8BindingTestScope::create(m_isolate); // FIXME: Create a new world and pass it to V8PerContextData.
m_perContextData = V8PerContextData::create(m_context.newLocal(m_isolate), 0);
} }
void TearDown() void TearDown()
{ {
m_scope.clear(); m_perContextData.clear();
} }
V8PromiseCustom::PromiseState state(ScriptPromise promise) V8PromiseCustom::PromiseState state(ScriptPromise promise)
...@@ -67,9 +71,10 @@ public: ...@@ -67,9 +71,10 @@ public:
protected: protected:
v8::Isolate* m_isolate; v8::Isolate* m_isolate;
v8::HandleScope m_handleScope;
private: ScopedPersistent<v8::Context> m_context;
OwnPtr<V8BindingTestScope> m_scope; v8::Context::Scope m_contextScope;
OwnPtr<V8PerContextData> m_perContextData;
}; };
TEST_F(ScriptPromiseTest, castPromise) TEST_F(ScriptPromiseTest, castPromise)
......
...@@ -734,18 +734,4 @@ v8::Isolate* toIsolate(LocalFrame* frame) ...@@ -734,18 +734,4 @@ v8::Isolate* toIsolate(LocalFrame* frame)
return frame->script().isolate(); return frame->script().isolate();
} }
PassOwnPtr<V8BindingTestScope> V8BindingTestScope::create(v8::Isolate* isolate)
{
return adoptPtr(new V8BindingTestScope(isolate));
}
V8BindingTestScope::V8BindingTestScope(v8::Isolate* isolate)
: m_handleScope(isolate)
, m_context(v8::Context::New(isolate))
, m_contextScope(m_context)
, m_world(DOMWrapperWorld::create())
, m_perContextData(V8PerContextData::create(m_context, m_world.get()))
{
}
} // namespace WebCore } // namespace WebCore
...@@ -46,683 +46,673 @@ ...@@ -46,683 +46,673 @@
namespace WebCore { namespace WebCore {
class DOMWindow; class DOMWindow;
class Document; class Document;
class EventListener; class EventListener;
class ExecutionContext; class ExceptionState;
class ExceptionState; class LocalFrame;
class LocalFrame; class NodeFilter;
class NodeFilter; class ExecutionContext;
class ScriptWrappable; class ScriptWrappable;
class V8PerContextData; class XPathNSResolver;
class XPathNSResolver;
const int kMaxRecursionDepth = 22;
const int kMaxRecursionDepth = 22;
// Schedule a JavaScript error to be thrown.
// Schedule a JavaScript error to be thrown. v8::Handle<v8::Value> throwError(V8ErrorType, const String&, v8::Isolate*);
v8::Handle<v8::Value> throwError(V8ErrorType, const String&, v8::Isolate*);
// Schedule a JavaScript error to be thrown.
// Schedule a JavaScript error to be thrown. v8::Handle<v8::Value> throwError(v8::Handle<v8::Value>, v8::Isolate*);
v8::Handle<v8::Value> throwError(v8::Handle<v8::Value>, v8::Isolate*);
// A helper for throwing JavaScript TypeError.
// A helper for throwing JavaScript TypeError. v8::Handle<v8::Value> throwTypeError(const String&, v8::Isolate*);
v8::Handle<v8::Value> throwTypeError(const String&, v8::Isolate*);
v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator();
v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator();
inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& info, int index)
inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& info, int index) {
{ return index >= info.Length() ? v8::Local<v8::Value>() : info[index];
return index >= info.Length() ? v8::Local<v8::Value>() : info[index]; }
}
template<typename CallbackInfo, typename V>
template<typename CallbackInfo, typename V> inline void v8SetReturnValue(const CallbackInfo& info, V v)
inline void v8SetReturnValue(const CallbackInfo& info, V v) {
{ info.GetReturnValue().Set(v);
info.GetReturnValue().Set(v); }
}
template<typename CallbackInfo>
template<typename CallbackInfo> inline void v8SetReturnValueBool(const CallbackInfo& info, bool v)
inline void v8SetReturnValueBool(const CallbackInfo& info, bool v) {
{ info.GetReturnValue().Set(v);
info.GetReturnValue().Set(v); }
}
template<typename CallbackInfo>
template<typename CallbackInfo> inline void v8SetReturnValueInt(const CallbackInfo& info, int v)
inline void v8SetReturnValueInt(const CallbackInfo& info, int v) {
{ info.GetReturnValue().Set(v);
info.GetReturnValue().Set(v); }
}
template<typename CallbackInfo>
template<typename CallbackInfo> inline void v8SetReturnValueUnsigned(const CallbackInfo& info, unsigned v)
inline void v8SetReturnValueUnsigned(const CallbackInfo& info, unsigned v) {
{ info.GetReturnValue().Set(v);
info.GetReturnValue().Set(v); }
}
template<typename CallbackInfo>
template<typename CallbackInfo> inline void v8SetReturnValueNull(const CallbackInfo& info)
inline void v8SetReturnValueNull(const CallbackInfo& info) {
{ info.GetReturnValue().SetNull();
info.GetReturnValue().SetNull(); }
}
template<typename CallbackInfo>
template<typename CallbackInfo> inline void v8SetReturnValueUndefined(const CallbackInfo& info)
inline void v8SetReturnValueUndefined(const CallbackInfo& info) {
{ info.GetReturnValue().SetUndefined();
info.GetReturnValue().SetUndefined(); }
}
template<typename CallbackInfo>
template<typename CallbackInfo> inline void v8SetReturnValueEmptyString(const CallbackInfo& info)
inline void v8SetReturnValueEmptyString(const CallbackInfo& info) {
{ info.GetReturnValue().SetEmptyString();
info.GetReturnValue().SetEmptyString(); }
}
template <class CallbackInfo>
template <class CallbackInfo> inline void v8SetReturnValueString(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
inline void v8SetReturnValueString(const CallbackInfo& info, const String& string, v8::Isolate* isolate) {
{ if (string.isNull()) {
if (string.isNull()) { v8SetReturnValueEmptyString(info);
v8SetReturnValueEmptyString(info); return;
return; }
} V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl()); }
}
template <class CallbackInfo>
template <class CallbackInfo> inline void v8SetReturnValueStringOrNull(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
inline void v8SetReturnValueStringOrNull(const CallbackInfo& info, const String& string, v8::Isolate* isolate) {
{ if (string.isNull()) {
if (string.isNull()) { v8SetReturnValueNull(info);
v8SetReturnValueNull(info); return;
return; }
} V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl()); }
}
template <class CallbackInfo>
template <class CallbackInfo> inline void v8SetReturnValueStringOrUndefined(const CallbackInfo& info, const String& string, v8::Isolate* isolate)
inline void v8SetReturnValueStringOrUndefined(const CallbackInfo& info, const String& string, v8::Isolate* isolate) {
{ if (string.isNull()) {
if (string.isNull()) { v8SetReturnValueUndefined(info);
v8SetReturnValueUndefined(info); return;
return; }
} V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl());
V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info.GetReturnValue(), string.impl()); }
}
// Convert v8::String to a WTF::String. If the V8 string is not already
// Convert v8::String to a WTF::String. If the V8 string is not already // an external string then it is transformed into an external string at this
// an external string then it is transformed into an external string at this // point to avoid repeated conversions.
// point to avoid repeated conversions. inline String toCoreString(v8::Handle<v8::String> value)
inline String toCoreString(v8::Handle<v8::String> value) {
{ return v8StringToWebCoreString<String>(value, Externalize);
return v8StringToWebCoreString<String>(value, Externalize); }
}
inline String toCoreStringWithNullCheck(v8::Handle<v8::String> value)
inline String toCoreStringWithNullCheck(v8::Handle<v8::String> value) {
{ if (value.IsEmpty() || value->IsNull())
if (value.IsEmpty() || value->IsNull()) return String();
return String(); return toCoreString(value);
return toCoreString(value); }
}
inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::String> value)
inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::String> value) {
{ if (value.IsEmpty() || value->IsNull() || value->IsUndefined())
if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) return String();
return String(); return toCoreString(value);
return toCoreString(value); }
}
inline AtomicString toCoreAtomicString(v8::Handle<v8::String> value)
inline AtomicString toCoreAtomicString(v8::Handle<v8::String> value) {
{ return v8StringToWebCoreString<AtomicString>(value, Externalize);
return v8StringToWebCoreString<AtomicString>(value, Externalize); }
}
// This method will return a null String if the v8::Value does not contain a v8::String.
// This method will return a null String if the v8::Value does not contain a v8::String. // It will not call ToString() on the v8::Value. If you want ToString() to be called,
// It will not call ToString() on the v8::Value. If you want ToString() to be called, // please use the V8TRYCATCH_FOR_V8STRINGRESOURCE_*() macros instead.
// please use the V8TRYCATCH_FOR_V8STRINGRESOURCE_*() macros instead. inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::Value> value)
inline String toCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::Value> value) {
{ if (value.IsEmpty() || !value->IsString())
if (value.IsEmpty() || !value->IsString()) return String();
return String();
return toCoreString(value.As<v8::String>()); return toCoreString(value.As<v8::String>());
} }
// Convert a string to a V8 string. // Convert a string to a V8 string.
// Return a V8 external string that shares the underlying buffer with the given // Return a V8 external string that shares the underlying buffer with the given
// WebCore string. The reference counting mechanism is used to keep the // WebCore string. The reference counting mechanism is used to keep the
// underlying buffer alive while the string is still live in the V8 engine. // underlying buffer alive while the string is still live in the V8 engine.
inline v8::Handle<v8::String> v8String(v8::Isolate* isolate, const String& string) inline v8::Handle<v8::String> v8String(v8::Isolate* isolate, const String& string)
{ {
if (string.isNull()) if (string.isNull())
return v8::String::Empty(isolate); return v8::String::Empty(isolate);
return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate); return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
} }
inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str) inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str)
{ {
ASSERT(isolate); ASSERT(isolate);
return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, strlen(str)); return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, strlen(str));
} }
inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str, size_t length) inline v8::Handle<v8::String> v8AtomicString(v8::Isolate* isolate, const char* str, size_t length)
{ {
ASSERT(isolate); ASSERT(isolate);
return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, length); return v8::String::NewFromUtf8(isolate, str, v8::String::kInternalizedString, length);
} }
inline v8::Handle<v8::Value> v8Undefined() inline v8::Handle<v8::Value> v8Undefined()
{ {
return v8::Handle<v8::Value>(); return v8::Handle<v8::Value>();
} }
template <class T> template <class T>
struct V8ValueTraits { struct V8ValueTraits {
static inline v8::Handle<v8::Value> arrayV8Value(const T& value, v8::Isolate* isolate) static inline v8::Handle<v8::Value> arrayV8Value(const T& value, v8::Isolate* isolate)
{ {
return toV8(WTF::getPtr(value), v8::Handle<v8::Object>(), isolate); return toV8(WTF::getPtr(value), v8::Handle<v8::Object>(), isolate);
} }
}; };
template<> template<>
struct V8ValueTraits<String> { struct V8ValueTraits<String> {
static inline v8::Handle<v8::Value> arrayV8Value(const String& value, v8::Isolate* isolate) static inline v8::Handle<v8::Value> arrayV8Value(const String& value, v8::Isolate* isolate)
{ {
return v8String(isolate, value); return v8String(isolate, value);
} }
}; };
template<> template<>
struct V8ValueTraits<AtomicString> { struct V8ValueTraits<AtomicString> {
static inline v8::Handle<v8::Value> arrayV8Value(const AtomicString& value, v8::Isolate* isolate) static inline v8::Handle<v8::Value> arrayV8Value(const AtomicString& value, v8::Isolate* isolate)
{ {
return v8String(isolate, value); return v8String(isolate, value);
} }
}; };
template<> template<>
struct V8ValueTraits<unsigned> { struct V8ValueTraits<unsigned> {
static inline v8::Handle<v8::Value> arrayV8Value(const unsigned& value, v8::Isolate* isolate) static inline v8::Handle<v8::Value> arrayV8Value(const unsigned& value, v8::Isolate* isolate)
{ {
return v8::Integer::NewFromUnsigned(isolate, value); return v8::Integer::NewFromUnsigned(isolate, value);
} }
}; };
template<> template<>
struct V8ValueTraits<unsigned long> { struct V8ValueTraits<unsigned long> {
static inline v8::Handle<v8::Value> arrayV8Value(const unsigned long& value, v8::Isolate* isolate) static inline v8::Handle<v8::Value> arrayV8Value(const unsigned long& value, v8::Isolate* isolate)
{ {
return v8::Integer::NewFromUnsigned(isolate, value); return v8::Integer::NewFromUnsigned(isolate, value);
} }
}; };
template<> template<>
struct V8ValueTraits<float> { struct V8ValueTraits<float> {
static inline v8::Handle<v8::Value> arrayV8Value(const float& value, v8::Isolate* isolate) static inline v8::Handle<v8::Value> arrayV8Value(const float& value, v8::Isolate* isolate)
{ {
return v8::Number::New(isolate, value); return v8::Number::New(isolate, value);
} }
}; };
template<> template<>
struct V8ValueTraits<double> { struct V8ValueTraits<double> {
static inline v8::Handle<v8::Value> arrayV8Value(const double& value, v8::Isolate* isolate) static inline v8::Handle<v8::Value> arrayV8Value(const double& value, v8::Isolate* isolate)
{ {
return v8::Number::New(isolate, value); return v8::Number::New(isolate, value);
} }
}; };
template<typename T, size_t inlineCapacity> template<typename T, size_t inlineCapacity>
v8::Handle<v8::Value> v8Array(const Vector<T, inlineCapacity>& iterator, v8::Isolate* isolate) v8::Handle<v8::Value> v8Array(const Vector<T, inlineCapacity>& iterator, v8::Isolate* isolate)
{ {
v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size()); v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
int index = 0; int index = 0;
typename Vector<T, inlineCapacity>::const_iterator end = iterator.end(); typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();
typedef V8ValueTraits<T> TraitsType; typedef V8ValueTraits<T> TraitsType;
for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter) for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
result->Set(v8::Integer::New(isolate, index++), TraitsType::arrayV8Value(*iter, isolate)); result->Set(v8::Integer::New(isolate, index++), TraitsType::arrayV8Value(*iter, isolate));
return result; return result;
} }
template<typename T, size_t inlineCapacity> template<typename T, size_t inlineCapacity>
v8::Handle<v8::Value> v8Array(const HeapVector<T, inlineCapacity>& iterator, v8::Isolate* isolate) v8::Handle<v8::Value> v8Array(const HeapVector<T, inlineCapacity>& iterator, v8::Isolate* isolate)
{ {
v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size()); v8::Local<v8::Array> result = v8::Array::New(isolate, iterator.size());
int index = 0; int index = 0;
typename HeapVector<T, inlineCapacity>::const_iterator end = iterator.end(); typename HeapVector<T, inlineCapacity>::const_iterator end = iterator.end();
typedef V8ValueTraits<T> TraitsType; typedef V8ValueTraits<T> TraitsType;
for (typename HeapVector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter) for (typename HeapVector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
result->Set(v8::Integer::New(isolate, index++), TraitsType::arrayV8Value(*iter, isolate)); result->Set(v8::Integer::New(isolate, index++), TraitsType::arrayV8Value(*iter, isolate));
return result; return result;
} }
// Conversion flags, used in toIntXX/toUIntXX. // Conversion flags, used in toIntXX/toUIntXX.
enum IntegerConversionConfiguration { enum IntegerConversionConfiguration {
NormalConversion, NormalConversion,
EnforceRange, EnforceRange,
Clamp Clamp
}; };
// Convert a value to a 8-bit signed integer. The conversion fails if the // Convert a value to a 8-bit signed integer. The conversion fails if the
// value cannot be converted to a number or the range violated per WebIDL: // value cannot be converted to a number or the range violated per WebIDL:
// http://www.w3.org/TR/WebIDL/#es-byte // http://www.w3.org/TR/WebIDL/#es-byte
int8_t toInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&); int8_t toInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
inline int8_t toInt8(v8::Handle<v8::Value> value, ExceptionState& exceptionState) inline int8_t toInt8(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{ {
return toInt8(value, NormalConversion, exceptionState); return toInt8(value, NormalConversion, exceptionState);
} }
// Convert a value to a 8-bit integer assuming the conversion cannot fail. // Convert a value to a 8-bit integer assuming the conversion cannot fail.
int8_t toInt8(v8::Handle<v8::Value>); int8_t toInt8(v8::Handle<v8::Value>);
// Convert a value to a 8-bit unsigned integer. The conversion fails if the // Convert a value to a 8-bit unsigned integer. The conversion fails if the
// value cannot be converted to a number or the range violated per WebIDL: // value cannot be converted to a number or the range violated per WebIDL:
// http://www.w3.org/TR/WebIDL/#es-octet // http://www.w3.org/TR/WebIDL/#es-octet
uint8_t toUInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&); uint8_t toUInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
inline uint8_t toUInt8(v8::Handle<v8::Value> value, ExceptionState& exceptionState) inline uint8_t toUInt8(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{ {
return toUInt8(value, NormalConversion, exceptionState); return toUInt8(value, NormalConversion, exceptionState);
} }
// Convert a value to a 8-bit unsigned integer assuming the conversion cannot fail. // Convert a value to a 8-bit unsigned integer assuming the conversion cannot fail.
uint8_t toUInt8(v8::Handle<v8::Value>); uint8_t toUInt8(v8::Handle<v8::Value>);
// Convert a value to a 16-bit signed integer. The conversion fails if the // Convert a value to a 16-bit signed integer. The conversion fails if the
// value cannot be converted to a number or the range violated per WebIDL: // value cannot be converted to a number or the range violated per WebIDL:
// http://www.w3.org/TR/WebIDL/#es-short // http://www.w3.org/TR/WebIDL/#es-short
int16_t toInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&); int16_t toInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
inline int16_t toInt16(v8::Handle<v8::Value> value, ExceptionState& exceptionState) inline int16_t toInt16(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{ {
return toInt16(value, NormalConversion, exceptionState); return toInt16(value, NormalConversion, exceptionState);
} }
// Convert a value to a 16-bit integer assuming the conversion cannot fail. // Convert a value to a 16-bit integer assuming the conversion cannot fail.
int16_t toInt16(v8::Handle<v8::Value>); int16_t toInt16(v8::Handle<v8::Value>);
// Convert a value to a 16-bit unsigned integer. The conversion fails if the // Convert a value to a 16-bit unsigned integer. The conversion fails if the
// value cannot be converted to a number or the range violated per WebIDL: // value cannot be converted to a number or the range violated per WebIDL:
// http://www.w3.org/TR/WebIDL/#es-unsigned-short // http://www.w3.org/TR/WebIDL/#es-unsigned-short
uint16_t toUInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&); uint16_t toUInt16(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
inline uint16_t toUInt16(v8::Handle<v8::Value> value, ExceptionState& exceptionState) inline uint16_t toUInt16(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{ {
return toUInt16(value, NormalConversion, exceptionState); return toUInt16(value, NormalConversion, exceptionState);
} }
// Convert a value to a 16-bit unsigned integer assuming the conversion cannot fail. // Convert a value to a 16-bit unsigned integer assuming the conversion cannot fail.
uint16_t toUInt16(v8::Handle<v8::Value>); uint16_t toUInt16(v8::Handle<v8::Value>);
// Convert a value to a 32-bit signed integer. The conversion fails if the // Convert a value to a 32-bit signed integer. The conversion fails if the
// value cannot be converted to a number or the range violated per WebIDL: // value cannot be converted to a number or the range violated per WebIDL:
// http://www.w3.org/TR/WebIDL/#es-long // http://www.w3.org/TR/WebIDL/#es-long
int32_t toInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&); int32_t toInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
inline int32_t toInt32(v8::Handle<v8::Value> value, ExceptionState& exceptionState) inline int32_t toInt32(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{ {
return toInt32(value, NormalConversion, exceptionState); return toInt32(value, NormalConversion, exceptionState);
} }
// Convert a value to a 32-bit integer assuming the conversion cannot fail. // Convert a value to a 32-bit integer assuming the conversion cannot fail.
int32_t toInt32(v8::Handle<v8::Value>); int32_t toInt32(v8::Handle<v8::Value>);
// Convert a value to a 32-bit unsigned integer. The conversion fails if the // Convert a value to a 32-bit unsigned integer. The conversion fails if the
// value cannot be converted to a number or the range violated per WebIDL: // value cannot be converted to a number or the range violated per WebIDL:
// http://www.w3.org/TR/WebIDL/#es-unsigned-long // http://www.w3.org/TR/WebIDL/#es-unsigned-long
uint32_t toUInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&); uint32_t toUInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
inline uint32_t toUInt32(v8::Handle<v8::Value> value, ExceptionState& exceptionState) inline uint32_t toUInt32(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{ {
return toUInt32(value, NormalConversion, exceptionState); return toUInt32(value, NormalConversion, exceptionState);
} }
// Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail. // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
uint32_t toUInt32(v8::Handle<v8::Value>); uint32_t toUInt32(v8::Handle<v8::Value>);
// Convert a value to a 64-bit signed integer. The conversion fails if the // Convert a value to a 64-bit signed integer. The conversion fails if the
// value cannot be converted to a number or the range violated per WebIDL: // value cannot be converted to a number or the range violated per WebIDL:
// http://www.w3.org/TR/WebIDL/#es-long-long // http://www.w3.org/TR/WebIDL/#es-long-long
int64_t toInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&); int64_t toInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
inline int64_t toInt64(v8::Handle<v8::Value> value, ExceptionState& exceptionState) inline int64_t toInt64(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{ {
return toInt64(value, NormalConversion, exceptionState); return toInt64(value, NormalConversion, exceptionState);
} }
// Convert a value to a 64-bit integer assuming the conversion cannot fail. // Convert a value to a 64-bit integer assuming the conversion cannot fail.
int64_t toInt64(v8::Handle<v8::Value>); int64_t toInt64(v8::Handle<v8::Value>);
// Convert a value to a 64-bit unsigned integer. The conversion fails if the // Convert a value to a 64-bit unsigned integer. The conversion fails if the
// value cannot be converted to a number or the range violated per WebIDL: // value cannot be converted to a number or the range violated per WebIDL:
// http://www.w3.org/TR/WebIDL/#es-unsigned-long-long // http://www.w3.org/TR/WebIDL/#es-unsigned-long-long
uint64_t toUInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&); uint64_t toUInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, ExceptionState&);
inline uint64_t toUInt64(v8::Handle<v8::Value> value, ExceptionState& exceptionState) inline uint64_t toUInt64(v8::Handle<v8::Value> value, ExceptionState& exceptionState)
{ {
return toUInt64(value, NormalConversion, exceptionState); return toUInt64(value, NormalConversion, exceptionState);
} }
// Convert a value to a 64-bit unsigned integer assuming the conversion cannot fail. // Convert a value to a 64-bit unsigned integer assuming the conversion cannot fail.
uint64_t toUInt64(v8::Handle<v8::Value>); uint64_t toUInt64(v8::Handle<v8::Value>);
// Convert a value to a single precision float, which might fail. // Convert a value to a single precision float, which might fail.
float toFloat(v8::Handle<v8::Value>, ExceptionState&); float toFloat(v8::Handle<v8::Value>, ExceptionState&);
// Convert a value to a single precision float assuming the conversion cannot fail. // Convert a value to a single precision float assuming the conversion cannot fail.
inline float toFloat(v8::Local<v8::Value> value) inline float toFloat(v8::Local<v8::Value> value)
{
return static_cast<float>(value->NumberValue());
}
inline v8::Handle<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate)
{
return value ? v8::True(isolate) : v8::False(isolate);
}
inline double toCoreDate(v8::Handle<v8::Value> object)
{
if (object->IsDate())
return v8::Handle<v8::Date>::Cast(object)->ValueOf();
if (object->IsNumber())
return object->NumberValue();
return std::numeric_limits<double>::quiet_NaN();
}
inline v8::Handle<v8::Value> v8DateOrNull(double value, v8::Isolate* isolate)
{
ASSERT(isolate);
return std::isfinite(value) ? v8::Date::New(isolate, value) : v8::Handle<v8::Value>::Cast(v8::Null(isolate));
}
// FIXME: Remove the special casing for NodeFilter and XPathNSResolver.
PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Isolate*);
PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*);
template<class T> struct NativeValueTraits;
template<>
struct NativeValueTraits<String> {
static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, value, String());
return stringValue;
}
};
template<>
struct NativeValueTraits<unsigned> {
static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
return toUInt32(value);
}
};
template<>
struct NativeValueTraits<float> {
static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{ {
return static_cast<float>(value->NumberValue()); return static_cast<float>(value->NumberValue());
} }
};
inline v8::Handle<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate)
template<> {
struct NativeValueTraits<double> { return value ? v8::True(isolate) : v8::False(isolate);
static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) }
{
return static_cast<double>(value->NumberValue()); inline double toCoreDate(v8::Handle<v8::Value> object)
} {
}; if (object->IsDate())
return v8::Handle<v8::Date>::Cast(object)->ValueOf();
template<> if (object->IsNumber())
struct NativeValueTraits<v8::Handle<v8::Value> > { return object->NumberValue();
static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate) return std::numeric_limits<double>::quiet_NaN();
{ }
return value;
} inline v8::Handle<v8::Value> v8DateOrNull(double value, v8::Isolate* isolate)
}; {
ASSERT(isolate);
// Converts a JavaScript value to an array as per the Web IDL specification: return std::isfinite(value) ? v8::Date::New(isolate, value) : v8::Handle<v8::Value>::Cast(v8::Null(isolate));
// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array }
template <class T, class V8T>
Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, uint32_t length, v8::Isolate* isolate, bool* success = 0) // FIXME: Remove the special casing for NodeFilter and XPathNSResolver.
{ PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>, v8::Isolate*);
Vector<RefPtr<T> > result; PassRefPtrWillBeRawPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*);
result.reserveInitialCapacity(length);
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value); template<class T> struct NativeValueTraits;
for (uint32_t i = 0; i < length; ++i) {
v8::Handle<v8::Value> element = object->Get(i); template<>
if (V8T::hasInstance(element, isolate)) { struct NativeValueTraits<String> {
v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element); static inline String nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
result.uncheckedAppend(V8T::toNative(elementObject)); {
} else { V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, stringValue, value, String());
if (success) return stringValue;
*success = false; }
throwTypeError("Invalid Array element type", isolate); };
template<>
struct NativeValueTraits<unsigned> {
static inline unsigned nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
return toUInt32(value);
}
};
template<>
struct NativeValueTraits<float> {
static inline float nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
return static_cast<float>(value->NumberValue());
}
};
template<>
struct NativeValueTraits<double> {
static inline double nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
return static_cast<double>(value->NumberValue());
}
};
template<>
struct NativeValueTraits<v8::Handle<v8::Value> > {
static inline v8::Handle<v8::Value> nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
{
return value;
}
};
// Converts a JavaScript value to an array as per the Web IDL specification:
// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
template <class T, class V8T>
Vector<RefPtr<T> > toRefPtrNativeArrayUnchecked(v8::Local<v8::Value> v8Value, uint32_t length, v8::Isolate* isolate, bool* success = 0)
{
Vector<RefPtr<T> > result;
result.reserveInitialCapacity(length);
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
for (uint32_t i = 0; i < length; ++i) {
v8::Handle<v8::Value> element = object->Get(i);
if (V8T::hasInstance(element, isolate)) {
v8::Handle<v8::Object> elementObject = v8::Handle<v8::Object>::Cast(element);
result.uncheckedAppend(V8T::toNative(elementObject));
} else {
if (success)
*success = false;
throwTypeError("Invalid Array element type", isolate);
return Vector<RefPtr<T> >();
}
}
return result;
}
v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*);
template <class T, class V8T>
Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0)
{
if (success)
*success = true;
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
uint32_t length = 0;
if (value->IsArray()) {
length = v8::Local<v8::Array>::Cast(v8Value)->Length();
} else if (toV8Sequence(value, length, isolate).IsEmpty()) {
throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
return Vector<RefPtr<T> >();
}
return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success);
}
template <class T, class V8T>
Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, bool* success = 0)
{
if (success)
*success = true;
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
uint32_t length = 0;
if (value->IsArray()) {
length = v8::Local<v8::Array>::Cast(v8Value)->Length();
} else if (toV8Sequence(value, length, isolate).IsEmpty()) {
throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName), isolate);
return Vector<RefPtr<T> >(); return Vector<RefPtr<T> >();
} }
return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success);
}
// Converts a JavaScript value to an array as per the Web IDL specification:
// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array
template <class T>
Vector<T> toNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate)
{
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
uint32_t length = 0;
if (value->IsArray()) {
length = v8::Local<v8::Array>::Cast(v8Value)->Length();
} else if (toV8Sequence(value, length, isolate).IsEmpty()) {
throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate);
return Vector<T>();
}
Vector<T> result;
result.reserveInitialCapacity(length);
typedef NativeValueTraits<T> TraitsType;
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
for (uint32_t i = 0; i < length; ++i)
result.uncheckedAppend(TraitsType::nativeValue(object->Get(i), isolate));
return result;
}
template <class T>
Vector<T> toNativeArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int startIndex)
{
ASSERT(startIndex <= info.Length());
Vector<T> result;
typedef NativeValueTraits<T> TraitsType;
int length = info.Length();
result.reserveInitialCapacity(length);
for (int i = startIndex; i < length; ++i)
result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate()));
return result;
}
// Validates that the passed object is a sequence type per WebIDL spec
// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence
inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate)
{
// Attempt converting to a sequence if the value is not already an array but is
// any kind of object except for a native Date object or a native RegExp object.
ASSERT(!value->IsArray());
// FIXME: Do we really need to special case Date and RegExp object?
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806
if (!value->IsObject() || value->IsDate() || value->IsRegExp()) {
// The caller is responsible for reporting a TypeError.
return v8Undefined();
}
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
v8::Local<v8::String> lengthSymbol = v8AtomicString(isolate, "length");
// FIXME: The specification states that the length property should be used as fallback, if value
// is not a platform object that supports indexed properties. If it supports indexed properties,
// length should actually be one greater than value’s maximum indexed property index.
V8TRYCATCH(v8::Local<v8::Value>, lengthValue, object->Get(lengthSymbol));
if (lengthValue->IsUndefined() || lengthValue->IsNull()) {
// The caller is responsible for reporting a TypeError.
return v8Undefined();
}
V8TRYCATCH(uint32_t, sequenceLength, lengthValue->Int32Value());
length = sequenceLength;
return v8Value;
}
v8::Isolate* toIsolate(ExecutionContext*);
v8::Isolate* toIsolate(LocalFrame*);
WrapperWorldType worldType(v8::Isolate*);
WrapperWorldType worldTypeInMainThread(v8::Isolate*);
DOMWindow* toDOMWindow(v8::Handle<v8::Value>, v8::Isolate*);
DOMWindow* toDOMWindow(v8::Handle<v8::Context>);
ExecutionContext* toExecutionContext(v8::Handle<v8::Context>);
DOMWindow* callingDOMWindow(v8::Isolate*);
ExecutionContext* callingExecutionContext(v8::Isolate*);
DOMWindow* enteredDOMWindow(v8::Isolate*);
Document* currentDocument(v8::Isolate*);
ExecutionContext* currentExecutionContext(v8::Isolate*);
// Returns a V8 context associated with a ExecutionContext and a DOMWrapperWorld.
// This method returns an empty context if there is no frame or the frame is already detached.
v8::Local<v8::Context> toV8Context(ExecutionContext*, DOMWrapperWorld*);
// Returns a V8 context associated with a LocalFrame and a DOMWrapperWorld.
// This method returns an empty context if the frame is already detached.
v8::Local<v8::Context> toV8Context(v8::Isolate*, LocalFrame*, DOMWrapperWorld*);
// Returns the frame object of the window object associated with
// a context, if the window is currently being displayed in the LocalFrame.
LocalFrame* toFrameIfNotDetached(v8::Handle<v8::Context>);
// If the current context causes out of memory, JavaScript setting
// is disabled and it returns true.
bool handleOutOfMemory();
v8::Local<v8::Value> handleMaxRecursionDepthExceeded(v8::Isolate*);
void crashIfV8IsDead();
inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
{
return value->IsNull() || value->IsUndefined();
}
v8::Handle<v8::Function> getBoundFunction(v8::Handle<v8::Function>);
// Attaches |environment| to |function| and returns it.
inline v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle<v8::Value> environment, v8::Isolate* isolate)
{
return v8::Function::New(isolate, function, environment);
}
// FIXME: This will be soon embedded in the generated code.
template<class Collection> static void indexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
{
Collection* collection = reinterpret_cast<Collection*>(info.Holder()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
int length = collection->length();
v8::Handle<v8::Array> properties = v8::Array::New(info.GetIsolate(), length);
for (int i = 0; i < length; ++i) {
// FIXME: Do we need to check that the item function returns a non-null value for this index?
v8::Handle<v8::Integer> integer = v8::Integer::New(info.GetIsolate(), i);
properties->Set(integer, integer);
}
v8SetReturnValue(info, properties);
} }
return result;
} v8::Local<v8::Value> getHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*);
v8::Local<v8::Value> getHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>);
v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value>, uint32_t& length, v8::Isolate*); bool setHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*, v8::Handle<v8::Value>);
bool setHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>, v8::Handle<v8::Value>);
template <class T, class V8T> bool deleteHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*);
Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate, bool* success = 0) bool deleteHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>);
{ v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, const char*);
if (success) v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, v8::Handle<v8::String>);
*success = true;
// These methods store hidden values into an array that is stored in the internal field of a DOM wrapper.
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); void addHiddenValueToArray(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
uint32_t length = 0; void removeHiddenValueFromArray(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
if (value->IsArray()) { void moveEventListenerToNewWrapper(v8::Handle<v8::Object>, EventListener* oldValue, v8::Local<v8::Value> newValue, int cacheIndex, v8::Isolate*);
length = v8::Local<v8::Array>::Cast(v8Value)->Length();
} else if (toV8Sequence(value, length, isolate).IsEmpty()) { // Converts a DOM object to a v8 value.
throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate); // This is a no-inline version of toV8(). If you want to call toV8()
return Vector<RefPtr<T> >(); // without creating #include cycles, you can use this function instead.
} // Each specialized implementation will be generated.
return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success); template<typename T>
} v8::Handle<v8::Value> toV8NoInline(T* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*);
template <class T, class V8T> // Result values for platform object 'deleter' methods,
Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, const String& propertyName, v8::Isolate* isolate, bool* success = 0) // http://www.w3.org/TR/WebIDL/#delete
{ enum DeleteResult {
if (success) DeleteSuccess,
*success = true; DeleteReject,
DeleteUnknownProperty
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); };
uint32_t length = 0;
if (value->IsArray()) { class V8IsolateInterruptor : public ThreadState::Interruptor {
length = v8::Local<v8::Array>::Cast(v8Value)->Length(); public:
} else if (toV8Sequence(value, length, isolate).IsEmpty()) { explicit V8IsolateInterruptor(v8::Isolate* isolate) : m_isolate(isolate) { }
throwTypeError(ExceptionMessages::notASequenceTypeProperty(propertyName), isolate);
return Vector<RefPtr<T> >(); static void onInterruptCallback(v8::Isolate* isolate, void* data)
} {
return toRefPtrNativeArrayUnchecked<T, V8T>(v8Value, length, isolate, success); reinterpret_cast<V8IsolateInterruptor*>(data)->onInterrupted();
} }
// Converts a JavaScript value to an array as per the Web IDL specification: virtual void requestInterrupt() OVERRIDE
// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-array {
template <class T> m_isolate->RequestInterrupt(&onInterruptCallback, this);
Vector<T> toNativeArray(v8::Handle<v8::Value> value, int argumentIndex, v8::Isolate* isolate) }
{
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value)); virtual void clearInterrupt() OVERRIDE
uint32_t length = 0; {
if (value->IsArray()) { m_isolate->ClearInterrupt();
length = v8::Local<v8::Array>::Cast(v8Value)->Length(); }
} else if (toV8Sequence(value, length, isolate).IsEmpty()) {
throwTypeError(ExceptionMessages::notAnArrayTypeArgumentOrValue(argumentIndex), isolate); private:
return Vector<T>(); v8::Isolate* m_isolate;
} };
Vector<T> result;
result.reserveInitialCapacity(length);
typedef NativeValueTraits<T> TraitsType;
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
for (uint32_t i = 0; i < length; ++i)
result.uncheckedAppend(TraitsType::nativeValue(object->Get(i), isolate));
return result;
}
template <class T>
Vector<T> toNativeArguments(const v8::FunctionCallbackInfo<v8::Value>& info, int startIndex)
{
ASSERT(startIndex <= info.Length());
Vector<T> result;
typedef NativeValueTraits<T> TraitsType;
int length = info.Length();
result.reserveInitialCapacity(length);
for (int i = startIndex; i < length; ++i)
result.uncheckedAppend(TraitsType::nativeValue(info[i], info.GetIsolate()));
return result;
}
// Validates that the passed object is a sequence type per WebIDL spec
// http://www.w3.org/TR/2012/CR-WebIDL-20120419/#es-sequence
inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate)
{
// Attempt converting to a sequence if the value is not already an array but is
// any kind of object except for a native Date object or a native RegExp object.
ASSERT(!value->IsArray());
// FIXME: Do we really need to special case Date and RegExp object?
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=22806
if (!value->IsObject() || value->IsDate() || value->IsRegExp()) {
// The caller is responsible for reporting a TypeError.
return v8Undefined();
}
v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(isolate, value));
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);
v8::Local<v8::String> lengthSymbol = v8AtomicString(isolate, "length");
// FIXME: The specification states that the length property should be used as fallback, if value
// is not a platform object that supports indexed properties. If it supports indexed properties,
// length should actually be one greater than value’s maximum indexed property index.
V8TRYCATCH(v8::Local<v8::Value>, lengthValue, object->Get(lengthSymbol));
if (lengthValue->IsUndefined() || lengthValue->IsNull()) {
// The caller is responsible for reporting a TypeError.
return v8Undefined();
}
V8TRYCATCH(uint32_t, sequenceLength, lengthValue->Int32Value());
length = sequenceLength;
return v8Value;
}
v8::Isolate* toIsolate(ExecutionContext*);
v8::Isolate* toIsolate(LocalFrame*);
WrapperWorldType worldType(v8::Isolate*);
WrapperWorldType worldTypeInMainThread(v8::Isolate*);
DOMWindow* toDOMWindow(v8::Handle<v8::Value>, v8::Isolate*);
DOMWindow* toDOMWindow(v8::Handle<v8::Context>);
ExecutionContext* toExecutionContext(v8::Handle<v8::Context>);
DOMWindow* callingDOMWindow(v8::Isolate*);
ExecutionContext* callingExecutionContext(v8::Isolate*);
DOMWindow* enteredDOMWindow(v8::Isolate*);
Document* currentDocument(v8::Isolate*);
ExecutionContext* currentExecutionContext(v8::Isolate*);
// Returns a V8 context associated with a ExecutionContext and a DOMWrapperWorld.
// This method returns an empty context if there is no frame or the frame is already detached.
v8::Local<v8::Context> toV8Context(ExecutionContext*, DOMWrapperWorld*);
// Returns a V8 context associated with a LocalFrame and a DOMWrapperWorld.
// This method returns an empty context if the frame is already detached.
v8::Local<v8::Context> toV8Context(v8::Isolate*, LocalFrame*, DOMWrapperWorld*);
// Returns the frame object of the window object associated with
// a context, if the window is currently being displayed in the LocalFrame.
LocalFrame* toFrameIfNotDetached(v8::Handle<v8::Context>);
// If the current context causes out of memory, JavaScript setting
// is disabled and it returns true.
bool handleOutOfMemory();
v8::Local<v8::Value> handleMaxRecursionDepthExceeded(v8::Isolate*);
void crashIfV8IsDead();
inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
{
return value->IsNull() || value->IsUndefined();
}
v8::Handle<v8::Function> getBoundFunction(v8::Handle<v8::Function>);
// Attaches |environment| to |function| and returns it.
inline v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle<v8::Value> environment, v8::Isolate* isolate)
{
return v8::Function::New(isolate, function, environment);
}
// FIXME: This will be soon embedded in the generated code.
template<class Collection> static void indexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
{
Collection* collection = reinterpret_cast<Collection*>(info.Holder()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
int length = collection->length();
v8::Handle<v8::Array> properties = v8::Array::New(info.GetIsolate(), length);
for (int i = 0; i < length; ++i) {
// FIXME: Do we need to check that the item function returns a non-null value for this index?
v8::Handle<v8::Integer> integer = v8::Integer::New(info.GetIsolate(), i);
properties->Set(integer, integer);
}
v8SetReturnValue(info, properties);
}
v8::Local<v8::Value> getHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*);
v8::Local<v8::Value> getHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>);
bool setHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*, v8::Handle<v8::Value>);
bool setHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>, v8::Handle<v8::Value>);
bool deleteHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, const char*);
bool deleteHiddenValue(v8::Isolate*, v8::Handle<v8::Object>, v8::Handle<v8::String>);
v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, const char*);
v8::Local<v8::Value> getHiddenValueFromMainWorldWrapper(v8::Isolate*, ScriptWrappable*, v8::Handle<v8::String>);
// These methods store hidden values into an array that is stored in the internal field of a DOM wrapper.
void addHiddenValueToArray(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
void removeHiddenValueFromArray(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex, v8::Isolate*);
void moveEventListenerToNewWrapper(v8::Handle<v8::Object>, EventListener* oldValue, v8::Local<v8::Value> newValue, int cacheIndex, v8::Isolate*);
// Converts a DOM object to a v8 value.
// This is a no-inline version of toV8(). If you want to call toV8()
// without creating #include cycles, you can use this function instead.
// Each specialized implementation will be generated.
template<typename T>
v8::Handle<v8::Value> toV8NoInline(T* impl, v8::Handle<v8::Object> creationContext, v8::Isolate*);
// Result values for platform object 'deleter' methods,
// http://www.w3.org/TR/WebIDL/#delete
enum DeleteResult {
DeleteSuccess,
DeleteReject,
DeleteUnknownProperty
};
class V8IsolateInterruptor : public ThreadState::Interruptor {
public:
explicit V8IsolateInterruptor(v8::Isolate* isolate) : m_isolate(isolate) { }
static void onInterruptCallback(v8::Isolate* isolate, void* data)
{
reinterpret_cast<V8IsolateInterruptor*>(data)->onInterrupted();
}
virtual void requestInterrupt() OVERRIDE
{
m_isolate->RequestInterrupt(&onInterruptCallback, this);
}
virtual void clearInterrupt() OVERRIDE
{
m_isolate->ClearInterrupt();
}
private:
v8::Isolate* m_isolate;
};
class V8BindingTestScope {
public:
static PassOwnPtr<V8BindingTestScope> create(v8::Isolate*);
private:
explicit V8BindingTestScope(v8::Isolate*);
v8::HandleScope m_handleScope;
v8::Handle<v8::Context> m_context;
v8::Context::Scope m_contextScope;
RefPtr<DOMWrapperWorld> m_world;
OwnPtr<V8PerContextData> m_perContextData;
};
} // namespace WebCore } // namespace WebCore
......
...@@ -68,7 +68,7 @@ WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalSc ...@@ -68,7 +68,7 @@ WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalSc
V8Initializer::initializeWorker(m_isolate); V8Initializer::initializeWorker(m_isolate);
v8::V8::Initialize(); v8::V8::Initialize();
V8PerIsolateData::ensureInitialized(m_isolate); V8PerIsolateData::ensureInitialized(m_isolate);
m_world = DOMWrapperWorld::create(WorkerWorldId); m_world = DOMWrapperWorld::create(WorkerWorldId, -1);
m_interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate)); m_interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate));
ThreadState::current()->addInterruptor(m_interruptor.get()); ThreadState::current()->addInterruptor(m_interruptor.get());
} }
......
...@@ -36,11 +36,18 @@ protected: ...@@ -36,11 +36,18 @@ protected:
class AnimationAnimationV8Test : public AnimationAnimationTest { class AnimationAnimationV8Test : public AnimationAnimationTest {
protected: protected:
AnimationAnimationV8Test() AnimationAnimationV8Test()
: m_isolate(v8::Isolate::GetCurrent()) : isolate(v8::Isolate::GetCurrent())
, m_scope(V8BindingTestScope::create(m_isolate)) , scope(isolate)
, context(v8::Context::New(isolate))
, contextScope(context)
{ {
} }
v8::Isolate* isolate;
v8::HandleScope scope;
v8::Local<v8::Context> context;
v8::Context::Scope contextScope;
PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput) PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput)
{ {
return Animation::createUnsafe(element, keyframeDictionaryVector, timingInput); return Animation::createUnsafe(element, keyframeDictionaryVector, timingInput);
...@@ -55,18 +62,13 @@ protected: ...@@ -55,18 +62,13 @@ protected:
{ {
return Animation::createUnsafe(element, keyframeDictionaryVector); return Animation::createUnsafe(element, keyframeDictionaryVector);
} }
v8::Isolate* m_isolate;
private:
OwnPtr<V8BindingTestScope> m_scope;
}; };
TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation) TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation)
{ {
Vector<Dictionary> jsKeyframes; Vector<Dictionary> jsKeyframes;
v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate); v8::Handle<v8::Object> keyframe1 = v8::Object::New(isolate);
v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate); v8::Handle<v8::Object> keyframe2 = v8::Object::New(isolate);
setV8ObjectPropertyAsString(keyframe1, "width", "100px"); setV8ObjectPropertyAsString(keyframe1, "width", "100px");
setV8ObjectPropertyAsString(keyframe1, "offset", "0"); setV8ObjectPropertyAsString(keyframe1, "offset", "0");
...@@ -75,8 +77,8 @@ TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation) ...@@ -75,8 +77,8 @@ TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation)
setV8ObjectPropertyAsString(keyframe2, "offset", "1"); setV8ObjectPropertyAsString(keyframe2, "offset", "1");
setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.3)"); setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.3)");
jsKeyframes.append(Dictionary(keyframe1, m_isolate)); jsKeyframes.append(Dictionary(keyframe1, isolate));
jsKeyframes.append(Dictionary(keyframe2, m_isolate)); jsKeyframes.append(Dictionary(keyframe2, isolate));
String value1; String value1;
ASSERT_TRUE(jsKeyframes[0].get("width", value1)); ASSERT_TRUE(jsKeyframes[0].get("width", value1));
...@@ -140,7 +142,7 @@ TEST_F(AnimationAnimationV8Test, SpecifiedGetters) ...@@ -140,7 +142,7 @@ TEST_F(AnimationAnimationV8Test, SpecifiedGetters)
{ {
Vector<Dictionary, 0> jsKeyframes; Vector<Dictionary, 0> jsKeyframes;
v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
setV8ObjectPropertyAsNumber(timingInput, "delay", 2); setV8ObjectPropertyAsNumber(timingInput, "delay", 2);
setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5); setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5);
setV8ObjectPropertyAsString(timingInput, "fill", "backwards"); setV8ObjectPropertyAsString(timingInput, "fill", "backwards");
...@@ -149,7 +151,7 @@ TEST_F(AnimationAnimationV8Test, SpecifiedGetters) ...@@ -149,7 +151,7 @@ TEST_F(AnimationAnimationV8Test, SpecifiedGetters)
setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2); setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2);
setV8ObjectPropertyAsString(timingInput, "direction", "reverse"); setV8ObjectPropertyAsString(timingInput, "direction", "reverse");
setV8ObjectPropertyAsString(timingInput, "easing", "step-start"); setV8ObjectPropertyAsString(timingInput, "easing", "step-start");
Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate); Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary); RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
...@@ -168,9 +170,9 @@ TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter) ...@@ -168,9 +170,9 @@ TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter)
{ {
Vector<Dictionary, 0> jsKeyframes; Vector<Dictionary, 0> jsKeyframes;
v8::Handle<v8::Object> timingInputWithDuration = v8::Object::New(m_isolate); v8::Handle<v8::Object> timingInputWithDuration = v8::Object::New(isolate);
setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5); setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5);
Dictionary timingInputDictionaryWithDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputWithDuration), m_isolate); Dictionary timingInputDictionaryWithDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputWithDuration), isolate);
RefPtr<Animation> animationWithDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryWithDuration); RefPtr<Animation> animationWithDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryWithDuration);
...@@ -186,8 +188,8 @@ TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter) ...@@ -186,8 +188,8 @@ TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter)
EXPECT_EQ("", stringDuration); EXPECT_EQ("", stringDuration);
v8::Handle<v8::Object> timingInputNoDuration = v8::Object::New(m_isolate); v8::Handle<v8::Object> timingInputNoDuration = v8::Object::New(isolate);
Dictionary timingInputDictionaryNoDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputNoDuration), m_isolate); Dictionary timingInputDictionaryNoDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputNoDuration), isolate);
RefPtr<Animation> animationNoDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryNoDuration); RefPtr<Animation> animationNoDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryNoDuration);
...@@ -206,8 +208,8 @@ TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter) ...@@ -206,8 +208,8 @@ TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter)
TEST_F(AnimationAnimationV8Test, SpecifiedSetters) TEST_F(AnimationAnimationV8Test, SpecifiedSetters)
{ {
Vector<Dictionary, 0> jsKeyframes; Vector<Dictionary, 0> jsKeyframes;
v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate); Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary); RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
RefPtr<TimedItemTiming> specified = animation->specified(); RefPtr<TimedItemTiming> specified = animation->specified();
...@@ -248,8 +250,8 @@ TEST_F(AnimationAnimationV8Test, SpecifiedSetters) ...@@ -248,8 +250,8 @@ TEST_F(AnimationAnimationV8Test, SpecifiedSetters)
TEST_F(AnimationAnimationV8Test, SetSpecifiedDuration) TEST_F(AnimationAnimationV8Test, SetSpecifiedDuration)
{ {
Vector<Dictionary, 0> jsKeyframes; Vector<Dictionary, 0> jsKeyframes;
v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate); Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary); RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
RefPtr<TimedItemTiming> specified = animation->specified(); RefPtr<TimedItemTiming> specified = animation->specified();
......
...@@ -17,11 +17,18 @@ namespace WebCore { ...@@ -17,11 +17,18 @@ namespace WebCore {
class AnimationAnimationTimingInputTest : public ::testing::Test { class AnimationAnimationTimingInputTest : public ::testing::Test {
protected: protected:
AnimationAnimationTimingInputTest() AnimationAnimationTimingInputTest()
: m_isolate(v8::Isolate::GetCurrent()) : isolate(v8::Isolate::GetCurrent())
, m_scope(V8BindingTestScope::create(m_isolate)) , scope(isolate)
, context(v8::Context::New(isolate))
, contextScope(context)
{ {
} }
v8::Isolate* isolate;
v8::HandleScope scope;
v8::Local<v8::Context> context;
v8::Context::Scope contextScope;
void populateTiming(Timing& timing, Dictionary timingInputDictionary) void populateTiming(Timing& timing, Dictionary timingInputDictionary)
{ {
Animation::populateTiming(timing, timingInputDictionary); Animation::populateTiming(timing, timingInputDictionary);
...@@ -29,9 +36,9 @@ protected: ...@@ -29,9 +36,9 @@ protected:
Timing applyTimingInputNumber(String timingProperty, double timingPropertyValue) Timing applyTimingInputNumber(String timingProperty, double timingPropertyValue)
{ {
v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
setV8ObjectPropertyAsNumber(timingInput, timingProperty, timingPropertyValue); setV8ObjectPropertyAsNumber(timingInput, timingProperty, timingPropertyValue);
Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate); Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
Timing timing; Timing timing;
populateTiming(timing, timingInputDictionary); populateTiming(timing, timingInputDictionary);
return timing; return timing;
...@@ -39,18 +46,13 @@ protected: ...@@ -39,18 +46,13 @@ protected:
Timing applyTimingInputString(String timingProperty, String timingPropertyValue) Timing applyTimingInputString(String timingProperty, String timingPropertyValue)
{ {
v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
setV8ObjectPropertyAsString(timingInput, timingProperty, timingPropertyValue); setV8ObjectPropertyAsString(timingInput, timingProperty, timingPropertyValue);
Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate); Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
Timing timing; Timing timing;
populateTiming(timing, timingInputDictionary); populateTiming(timing, timingInputDictionary);
return timing; return timing;
} }
v8::Isolate* m_isolate;
private:
OwnPtr<V8BindingTestScope> m_scope;
}; };
TEST_F(AnimationAnimationTimingInputTest, TimingInputStartDelay) TEST_F(AnimationAnimationTimingInputTest, TimingInputStartDelay)
...@@ -175,8 +177,8 @@ TEST_F(AnimationAnimationTimingInputTest, TimingInputEmpty) ...@@ -175,8 +177,8 @@ TEST_F(AnimationAnimationTimingInputTest, TimingInputEmpty)
Timing updatedTiming; Timing updatedTiming;
Timing controlTiming; Timing controlTiming;
v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate); v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate); Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
populateTiming(updatedTiming, timingInputDictionary); populateTiming(updatedTiming, timingInputDictionary);
EXPECT_EQ(controlTiming.startDelay, updatedTiming.startDelay); EXPECT_EQ(controlTiming.startDelay, updatedTiming.startDelay);
......
...@@ -72,7 +72,8 @@ NullExecutionContext::NullExecutionContext() ...@@ -72,7 +72,8 @@ NullExecutionContext::NullExecutionContext()
class IDBRequestTest : public testing::Test { class IDBRequestTest : public testing::Test {
public: public:
IDBRequestTest() IDBRequestTest()
: m_scope(V8BindingTestScope::create(v8::Isolate::GetCurrent())) : m_handleScope(v8::Isolate::GetCurrent())
, m_scope(v8::Context::New(v8::Isolate::GetCurrent()))
, m_context(adoptRef(new NullExecutionContext())) , m_context(adoptRef(new NullExecutionContext()))
{ {
} }
...@@ -83,7 +84,8 @@ public: ...@@ -83,7 +84,8 @@ public:
} }
private: private:
OwnPtr<V8BindingTestScope> m_scope; v8::HandleScope m_handleScope;
v8::Context::Scope m_scope;
RefPtr<ExecutionContext> m_context; RefPtr<ExecutionContext> m_context;
}; };
......
...@@ -50,7 +50,8 @@ namespace { ...@@ -50,7 +50,8 @@ namespace {
class IDBTransactionTest : public testing::Test { class IDBTransactionTest : public testing::Test {
public: public:
IDBTransactionTest() IDBTransactionTest()
: m_scope(V8BindingTestScope::create(v8::Isolate::GetCurrent())) : m_handleScope(v8::Isolate::GetCurrent())
, m_scope(v8::Context::New(v8::Isolate::GetCurrent()))
, m_document(Document::create()) , m_document(Document::create())
{ {
} }
...@@ -61,7 +62,8 @@ public: ...@@ -61,7 +62,8 @@ public:
} }
private: private:
OwnPtr<V8BindingTestScope> m_scope; v8::HandleScope m_handleScope;
v8::Context::Scope m_scope;
RefPtr<Document> m_document; RefPtr<Document> m_document;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment