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)#include "config.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8ValueCache.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "bindings/v8/V8Binding.h"
30e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "bindings/v8/V8Utilities.h"
31e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "wtf/text/StringHash.h"
32926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
35f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)static v8::Local<v8::String> makeExternalString(const String& string)
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (string.is8Bit()) {
38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        WebCoreStringResource8* stringResource = new WebCoreStringResource8(string);
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        v8::Local<v8::String> newString = v8::String::NewExternal(stringResource);
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (newString.IsEmpty())
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            delete stringResource;
42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return newString;
43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    WebCoreStringResource16* stringResource = new WebCoreStringResource16(string);
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Local<v8::String> newString = v8::String::NewExternal(stringResource);
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newString.IsEmpty())
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        delete stringResource;
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return newString;
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
52e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochv8::Handle<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, v8::Isolate* isolate)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!stringImpl->length())
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return v8::String::Empty(isolate);
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
58f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    if (!cachedV8String.isEmpty()) {
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_lastStringImpl = stringImpl;
60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_lastV8String = cachedV8String;
615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return cachedV8String.newLocal(isolate);
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    return createStringAndInsertIntoCache(stringImpl, isolate);
65e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
66e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
67f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void StringCache::setReturnValueFromStringSlow(v8::ReturnValue<v8::Value> returnValue, StringImpl* stringImpl)
68f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
69f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    if (!stringImpl->length()) {
70f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        returnValue.SetEmptyString();
71f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        return;
72f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    }
73f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
74f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
75f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    if (!cachedV8String.isEmpty()) {
76f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        m_lastStringImpl = stringImpl;
77f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        m_lastV8String = cachedV8String;
78f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        returnValue.Set(*cachedV8String.persistent());
79f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        return;
80f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    }
81f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
82f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    returnValue.Set(createStringAndInsertIntoCache(stringImpl, returnValue.GetIsolate()));
83f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
84f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
85e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochv8::Local<v8::String> StringCache::createStringAndInsertIntoCache(StringImpl* stringImpl, v8::Isolate* isolate)
86e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
87f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    ASSERT(!m_stringCache.contains(stringImpl));
88f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    ASSERT(stringImpl->length());
89f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    v8::Local<v8::String> newString = makeExternalString(String(stringImpl));
91f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    if (newString.IsEmpty())
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return newString;
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    v8::Persistent<v8::String> wrapper(isolate, newString);
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    stringImpl->ref();
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    wrapper.MarkIndependent(isolate);
98521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    wrapper.MakeWeak(stringImpl, &makeWeakCallback);
995267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    m_lastV8String = UnsafePersistent<v8::String>(wrapper);
100f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    m_lastStringImpl = stringImpl;
1015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    m_stringCache.set(stringImpl, m_lastV8String);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return newString;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
106f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)void StringCache::makeWeakCallback(v8::Isolate* isolate, v8::Persistent<v8::String>* wrapper, StringImpl* stringImpl)
107f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
108f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    StringCache* stringCache = V8PerIsolateData::from(isolate)->stringCache();
109f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    stringCache->m_lastStringImpl = 0;
110f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    stringCache->m_lastV8String.clear();
111f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    ASSERT(stringCache->m_stringCache.contains(stringImpl));
112f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    stringCache->m_stringCache.remove(stringImpl);
113f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    stringImpl->deref();
114f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    wrapper->Dispose(isolate);
115f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
116f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
118