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)
297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "bindings/core/v8/ExceptionState.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/Threading.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/AtomicString.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/text/WTFString.h"
33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include <v8.h>
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class ExternalStringVisitor;
38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// WebCoreStringResource is a helper class for v8ExternalString. It is used
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// to manage the life-cycle of the underlying buffer of the external string.
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class WebCoreStringResourceBase {
42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public:
43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    explicit WebCoreStringResourceBase(const String& string)
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        : m_plainString(string)
45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
46197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_threadId = WTF::currentThread();
48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(!string.isNull());
50a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string));
51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    explicit WebCoreStringResourceBase(const AtomicString& string)
54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        : m_plainString(string.string())
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        , m_atomicString(string)
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_threadId = WTF::currentThread();
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(!string.isNull());
61a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string));
62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual ~WebCoreStringResourceBase()
65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
66197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(m_threadId == WTF::currentThread());
68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        int reducedExternalMemory = -memoryConsumption(m_plainString);
70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull())
71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            reducedExternalMemory -= memoryConsumption(m_atomicString.string());
72a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory);
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const String& webcoreString() { return m_plainString; }
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const AtomicString& atomicString()
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ASSERT(m_threadId == WTF::currentThread());
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_atomicString.isNull()) {
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            m_atomicString = AtomicString(m_plainString);
84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ASSERT(!m_atomicString.isNull());
85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (m_plainString.impl() != m_atomicString.impl())
86a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(m_atomicString.string()));
87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return m_atomicString;
89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)protected:
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // A shallow copy of the string. Keeps the string buffer alive until the V8 engine garbage collects it.
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    String m_plainString;
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // If this string is atomic or has been made atomic earlier the
95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // atomic string is held here. In the case where the string starts
96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // off non-atomic and becomes atomic later it is necessary to keep
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // the original string alive because v8 may keep derived pointers
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // into that string.
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    AtomicString m_atomicString;
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)private:
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    static int memoryConsumption(const String& string)
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return string.length() * (string.is8Bit() ? sizeof(LChar) : sizeof(UChar));
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    WTF::ThreadIdentifier m_threadId;
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#endif
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class WebCoreStringResource16 FINAL : public WebCoreStringResourceBase, public v8::String::ExternalStringResource {
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public:
113591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    explicit WebCoreStringResource16(const String& string)
114591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        : WebCoreStringResourceBase(string)
115591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
116591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT(!string.is8Bit());
117591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
118591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
119591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    explicit WebCoreStringResource16(const AtomicString& string)
120591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        : WebCoreStringResourceBase(string)
121591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
122591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT(!string.is8Bit());
123591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual size_t length() const OVERRIDE { return m_plainString.impl()->length(); }
126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual const uint16_t* data() const OVERRIDE
127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
128591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return reinterpret_cast<const uint16_t*>(m_plainString.impl()->characters16());
129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class WebCoreStringResource8 FINAL : public WebCoreStringResourceBase, public v8::String::ExternalAsciiStringResource {
133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public:
134591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    explicit WebCoreStringResource8(const String& string)
135591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        : WebCoreStringResourceBase(string)
136591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
137591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT(string.is8Bit());
138591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
139591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
140591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    explicit WebCoreStringResource8(const AtomicString& string)
141591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        : WebCoreStringResourceBase(string)
142591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    {
143591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT(string.is8Bit());
144591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    }
145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual size_t length() const OVERRIDE { return m_plainString.impl()->length(); }
147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    virtual const char* data() const OVERRIDE
148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return reinterpret_cast<const char*>(m_plainString.impl()->characters8());
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum ExternalMode {
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Externalize,
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DoNotExternalize
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename StringType>
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)StringType v8StringToWebCoreString(v8::Handle<v8::String>, ExternalMode);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String int32ToWebCoreString(int value);
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// V8StringResource is an adapter class that converts V8 values to Strings
163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// or AtomicStrings as appropriate, using multiple typecast operators.
164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)enum V8StringResourceMode {
165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    DefaultMode,
166197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    TreatNullAsEmptyString,
167197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    TreatNullAsNullString,
168197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    TreatNullAndUndefinedAsNullString
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template <V8StringResourceMode Mode = DefaultMode>
172926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class V8StringResource {
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
174d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    V8StringResource()
175d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        : m_mode(Externalize)
176d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
177d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
178d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    V8StringResource(v8::Handle<v8::Value> object)
180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        : m_v8Object(object)
181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        , m_mode(Externalize)
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
184926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
185d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    void operator=(v8::Handle<v8::Value> object)
186d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    {
187d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_v8Object = object;
188d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
189d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
1905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    void operator=(const String& string)
1915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    {
1925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        setString(string);
1935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    }
1945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
195197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    void operator=(std::nullptr_t)
196197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
197197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        setString(String());
198197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
199197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
200323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    bool prepare()
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (prepareFast())
2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return true;
2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_v8Object = m_v8Object->ToString();
2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Handle the case where an exception is thrown as part of invoking toString on the object.
2077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (m_v8Object.IsEmpty())
2087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return false;
2097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return true;
2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool prepare(ExceptionState& exceptionState)
2137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (prepareFast())
2157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return true;
2167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        v8::TryCatch block;
2187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_v8Object = m_v8Object->ToString();
2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Handle the case where an exception is thrown as part of invoking toString on the object.
2207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (block.HasCaught()) {
2217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            exceptionState.rethrowV8Exception(block.Exception());
2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return false;
2237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        }
2247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return true;
2257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
2267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    operator String() const { return toString<String>(); }
2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    operator AtomicString() const { return toString<AtomicString>(); }
2297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprivate:
2317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool prepareFast()
2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_v8Object.IsEmpty())
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
236323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (!isValid()) {
237197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            setString(fallbackString());
238323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return true;
239323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        }
240323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (LIKELY(m_v8Object->IsString()))
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (LIKELY(m_v8Object->IsInt32())) {
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            setString(int32ToWebCoreString(m_v8Object->Int32Value()));
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_mode = DoNotExternalize;
2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return false;
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
252323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
253323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    bool isValid() const;
254197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String fallbackString() const;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setString(const String& string)
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_string = string;
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_v8Object.Clear(); // To signal that String is ready.
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template <class StringType>
2638abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    StringType toString() const
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (LIKELY(!m_v8Object.IsEmpty()))
2668abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            return v8StringToWebCoreString<StringType>(const_cast<v8::Handle<v8::Value>*>(&m_v8Object)->As<v8::String>(), m_mode);
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return StringType(m_string);
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    v8::Handle<v8::Value> m_v8Object;
272926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ExternalMode m_mode;
273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    String m_string;
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
276323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)template<> inline bool V8StringResource<DefaultMode>::isValid() const
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
278323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return true;
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
281197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<> inline String V8StringResource<DefaultMode>::fallbackString() const
282197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
283197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT_NOT_REACHED();
284197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return String();
285197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
286197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
287197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<> inline bool V8StringResource<TreatNullAsEmptyString>::isValid() const
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
289323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return !m_v8Object->IsNull();
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
292197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<> inline String V8StringResource<TreatNullAsEmptyString>::fallbackString() const
293197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
294197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return emptyString();
295197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
296197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
297197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<> inline bool V8StringResource<TreatNullAsNullString>::isValid() const
298197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
299197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return !m_v8Object->IsNull();
300197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
301197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
302197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<> inline String V8StringResource<TreatNullAsNullString>::fallbackString() const
303197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
304197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return String();
305197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
306197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
307197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<> inline bool V8StringResource<TreatNullAndUndefinedAsNullString>::isValid() const
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
309323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return !m_v8Object->IsNull() && !m_v8Object->IsUndefined();
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
31102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
312197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<> inline String V8StringResource<TreatNullAndUndefinedAsNullString>::fallbackString() const
313197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
314197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return String();
315197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
316197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
317c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // V8StringResource_h
320