15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THE POSSIBILITY OF SUCH DAMAGE.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef V8StringResource_h
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define V8StringResource_h
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <v8.h>
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Threading.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/AtomicString.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/WTFString.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
36926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class ExternalStringVisitor;
37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// WebCoreStringResource is a helper class for v8ExternalString. It is used
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// to manage the life-cycle of the underlying buffer of the external string.
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class WebCoreStringResourceBase {
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public:
42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    explicit WebCoreStringResourceBase(const String& string)
43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        : m_plainString(string)
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#ifndef NDEBUG
46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_threadId = WTF::currentThread();
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(!string.isNull());
49a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string));
50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    explicit WebCoreStringResourceBase(const AtomicString& string)
53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        : m_plainString(string.string())
54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        , m_atomicString(string)
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#ifndef NDEBUG
57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_threadId = WTF::currentThread();
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(!string.isNull());
60a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string));
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual ~WebCoreStringResourceBase()
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#ifndef NDEBUG
66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(m_threadId == WTF::currentThread());
67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        int reducedExternalMemory = -memoryConsumption(m_plainString);
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull())
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            reducedExternalMemory -= memoryConsumption(m_atomicString.string());
71a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory);
72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const String& webcoreString() { return m_plainString; }
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const AtomicString& atomicString()
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#ifndef NDEBUG
79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(m_threadId == WTF::currentThread());
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_atomicString.isNull()) {
82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_atomicString = AtomicString(m_plainString);
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ASSERT(!m_atomicString.isNull());
84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (m_plainString.impl() != m_atomicString.impl())
85a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(m_atomicString.string()));
86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return m_atomicString;
88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)protected:
91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // A shallow copy of the string. Keeps the string buffer alive until the V8 engine garbage collects it.
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    String m_plainString;
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // If this string is atomic or has been made atomic earlier the
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // atomic string is held here. In the case where the string starts
95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // off non-atomic and becomes atomic later it is necessary to keep
96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // the original string alive because v8 may keep derived pointers
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // into that string.
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    AtomicString m_atomicString;
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)private:
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    static int memoryConsumption(const String& string)
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return string.length() * (string.is8Bit() ? sizeof(LChar) : sizeof(UChar));
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#ifndef NDEBUG
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    WTF::ThreadIdentifier m_threadId;
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class WebCoreStringResource16 FINAL : public WebCoreStringResourceBase, public v8::String::ExternalStringResource {
111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public:
112591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    explicit WebCoreStringResource16(const String& string)
113591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        : WebCoreStringResourceBase(string)
114591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
115591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT(!string.is8Bit());
116591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
117591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
118591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    explicit WebCoreStringResource16(const AtomicString& string)
119591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        : WebCoreStringResourceBase(string)
120591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
121591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT(!string.is8Bit());
122591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual size_t length() const OVERRIDE { return m_plainString.impl()->length(); }
125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual const uint16_t* data() const OVERRIDE
126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
127591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return reinterpret_cast<const uint16_t*>(m_plainString.impl()->characters16());
128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class WebCoreStringResource8 FINAL : public WebCoreStringResourceBase, public v8::String::ExternalAsciiStringResource {
132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public:
133591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    explicit WebCoreStringResource8(const String& string)
134591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        : WebCoreStringResourceBase(string)
135591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
136591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT(string.is8Bit());
137591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
138591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
139591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    explicit WebCoreStringResource8(const AtomicString& string)
140591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        : WebCoreStringResourceBase(string)
141591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
142591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT(string.is8Bit());
143591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual size_t length() const OVERRIDE { return m_plainString.impl()->length(); }
146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual const char* data() const OVERRIDE
147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return reinterpret_cast<const char*>(m_plainString.impl()->characters8());
149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum ExternalMode {
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Externalize,
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DoNotExternalize
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename StringType>
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)StringType v8StringToWebCoreString(v8::Handle<v8::String>, ExternalMode);
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String int32ToWebCoreString(int value);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// V8StringResource is an adapter class that converts V8 values to Strings
162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// or AtomicStrings as appropriate, using multiple typecast operators.
163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)enum V8StringResourceMode {
164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    DefaultMode,
165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    WithNullCheck,
166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    WithUndefinedOrNullCheck
167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <V8StringResourceMode Mode = DefaultMode>
170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class V8StringResource {
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
172d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    V8StringResource()
173d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        : m_mode(Externalize)
174d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
175d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
176d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    V8StringResource(v8::Handle<v8::Value> object)
178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        : m_v8Object(object)
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        , m_mode(Externalize)
180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
183d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void operator=(v8::Handle<v8::Value> object)
184d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
185d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_v8Object = object;
186d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
187d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
1885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    void operator=(const String& string)
1895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    {
1905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        setString(string);
1915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
1925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
193323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    bool prepare()
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_v8Object.IsEmpty())
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
198323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (!isValid()) {
199323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            setString(String());
200323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return true;
201323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        }
202323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (LIKELY(m_v8Object->IsString()))
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (LIKELY(m_v8Object->IsInt32())) {
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            setString(int32ToWebCoreString(m_v8Object->Int32Value()));
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mode = DoNotExternalize;
21210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        v8::TryCatch block;
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_v8Object = m_v8Object->ToString();
21410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        // Handle the case where an exception is thrown as part of invoking toString on the object.
21510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        if (block.HasCaught()) {
21610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            block.ReThrow();
21710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            return false;
21810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        }
21910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        return true;
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
221323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    operator String() const { return toString<String>(); }
222323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    operator AtomicString() const { return toString<AtomicString>(); }
223323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
224323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)private:
225323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    bool isValid() const;
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setString(const String& string)
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_string = string;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_v8Object.Clear(); // To signal that String is ready.
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template <class StringType>
2348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    StringType toString() const
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (LIKELY(!m_v8Object.IsEmpty()))
2378abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            return v8StringToWebCoreString<StringType>(const_cast<v8::Handle<v8::Value>*>(&m_v8Object)->As<v8::String>(), m_mode);
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return StringType(m_string);
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
242926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    v8::Handle<v8::Value> m_v8Object;
243926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ExternalMode m_mode;
244926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    String m_string;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
247323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)template<> inline bool V8StringResource<DefaultMode>::isValid() const
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
249323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return true;
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
252323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)template<> inline bool V8StringResource<WithNullCheck>::isValid() const
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
254323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return !m_v8Object->IsNull();
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
257323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)template<> inline bool V8StringResource<WithUndefinedOrNullCheck>::isValid() const
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
259323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return !m_v8Object->IsNull() && !m_v8Object->IsUndefined();
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
26102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // V8StringResource_h
265