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