Home | History | Annotate | Download | only in v8
      1 /*
      2  * Copyright (C) 2009 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "bindings/v8/V8ValueCache.h"
     28 
     29 #include "bindings/v8/V8Binding.h"
     30 #include "bindings/v8/V8Utilities.h"
     31 #include "wtf/text/StringHash.h"
     32 
     33 namespace WebCore {
     34 
     35 static v8::Local<v8::String> makeExternalString(const String& string, v8::Isolate* isolate)
     36 {
     37     if (string.is8Bit()) {
     38         WebCoreStringResource8* stringResource = new WebCoreStringResource8(string);
     39         v8::Local<v8::String> newString = v8::String::NewExternal(isolate, stringResource);
     40         if (newString.IsEmpty())
     41             delete stringResource;
     42         return newString;
     43     }
     44 
     45     WebCoreStringResource16* stringResource = new WebCoreStringResource16(string);
     46     v8::Local<v8::String> newString = v8::String::NewExternal(isolate, stringResource);
     47     if (newString.IsEmpty())
     48         delete stringResource;
     49     return newString;
     50 }
     51 
     52 v8::Handle<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, v8::Isolate* isolate)
     53 {
     54     if (!stringImpl->length())
     55         return v8::String::Empty(isolate);
     56 
     57     UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
     58     if (!cachedV8String.isEmpty()) {
     59         m_lastStringImpl = stringImpl;
     60         m_lastV8String = cachedV8String;
     61         return cachedV8String.newLocal(isolate);
     62     }
     63 
     64     return createStringAndInsertIntoCache(stringImpl, isolate);
     65 }
     66 
     67 void StringCache::setReturnValueFromStringSlow(v8::ReturnValue<v8::Value> returnValue, StringImpl* stringImpl)
     68 {
     69     if (!stringImpl->length()) {
     70         returnValue.SetEmptyString();
     71         return;
     72     }
     73 
     74     UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl);
     75     if (!cachedV8String.isEmpty()) {
     76         m_lastStringImpl = stringImpl;
     77         m_lastV8String = cachedV8String;
     78         returnValue.Set(*cachedV8String.persistent());
     79         return;
     80     }
     81 
     82     returnValue.Set(createStringAndInsertIntoCache(stringImpl, returnValue.GetIsolate()));
     83 }
     84 
     85 v8::Local<v8::String> StringCache::createStringAndInsertIntoCache(StringImpl* stringImpl, v8::Isolate* isolate)
     86 {
     87     ASSERT(!m_stringCache.contains(stringImpl));
     88     ASSERT(stringImpl->length());
     89 
     90     v8::Local<v8::String> newString = makeExternalString(String(stringImpl), isolate);
     91     if (newString.IsEmpty())
     92         return newString;
     93 
     94     v8::Persistent<v8::String> wrapper(isolate, newString);
     95 
     96     stringImpl->ref();
     97     wrapper.MarkIndependent();
     98     wrapper.SetWeak(stringImpl, &setWeakCallback);
     99     m_lastV8String = UnsafePersistent<v8::String>(wrapper);
    100     m_lastStringImpl = stringImpl;
    101     m_stringCache.set(stringImpl, m_lastV8String);
    102 
    103     return newString;
    104 }
    105 
    106 void StringCache::setWeakCallback(const v8::WeakCallbackData<v8::String, StringImpl>& data)
    107 {
    108     StringCache* stringCache = V8PerIsolateData::from(data.GetIsolate())->stringCache();
    109     stringCache->m_lastStringImpl = 0;
    110     stringCache->m_lastV8String.clear();
    111     ASSERT(stringCache->m_stringCache.contains(data.GetParameter()));
    112     stringCache->m_stringCache.get(data.GetParameter()).dispose();
    113     stringCache->m_stringCache.remove(data.GetParameter());
    114     data.GetParameter()->deref();
    115 }
    116 
    117 } // namespace WebCore
    118