v8::Local<v8::String> v8ExternalString(const String& string) { StringImpl* stringImpl = string.impl(); if (!stringImpl || !stringImpl->length()) return v8::String::Empty(); if (!stringImplCacheEnabled) return makeExternalString(string); StringCache& stringCache = getStringCache(); v8::String* cachedV8String = stringCache.get(stringImpl); if (cachedV8String) { v8::Persistent<v8::String> handle(cachedV8String); if (!handle.IsNearDeath() && !handle.IsEmpty()) return v8::Local<v8::String>::New(handle); } v8::Local<v8::String> newString = makeExternalString(string); if (newString.IsEmpty()) return newString; v8::Persistent<v8::String> wrapper = v8::Persistent<v8::String>::New(newString); if (wrapper.IsEmpty()) return newString; stringImpl->ref(); wrapper.MakeWeak(stringImpl, cachedStringCallback); stringCache.set(stringImpl, *wrapper); return newString; }
v8::Local<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, v8::Isolate* isolate) { if (!stringImpl->length()) return isolate ? v8::String::Empty(isolate) : v8::String::Empty(); v8::String* cachedV8String = m_stringCache.get(stringImpl); if (cachedV8String) { v8::Persistent<v8::String> handle(cachedV8String); if (handle.IsWeak()) { m_lastStringImpl = stringImpl; m_lastV8String = handle; return v8::Local<v8::String>::New(handle); } } v8::Local<v8::String> newString = makeExternalString(String(stringImpl)); if (newString.IsEmpty()) return newString; v8::Persistent<v8::String> wrapper = v8::Persistent<v8::String>::New(newString); if (wrapper.IsEmpty()) return newString; stringImpl->ref(); wrapper.MarkIndependent(); wrapper.MakeWeak(stringImpl, cachedStringCallback); m_stringCache.set(stringImpl, *wrapper); m_lastStringImpl = stringImpl; m_lastV8String = wrapper; return newString; }
v8::Handle<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, ReturnHandleType handleType, v8::Isolate* isolate) { if (!stringImpl->length()) return v8::String::Empty(isolate); UnsafePersistent<v8::String> cachedV8String = m_stringCache.get(stringImpl); if (cachedV8String.isWeak()) { m_lastStringImpl = stringImpl; m_lastV8String = cachedV8String; if (handleType == ReturnUnsafeHandle) return cachedV8String.handle(); return cachedV8String.newLocal(isolate); } v8::Local<v8::String> newString = makeExternalString(String(stringImpl)); if (newString.IsEmpty()) return newString; v8::Persistent<v8::String> wrapper(isolate, newString); stringImpl->ref(); wrapper.MarkIndependent(isolate); wrapper.MakeWeak(stringImpl, &makeWeakCallback); m_lastV8String = UnsafePersistent<v8::String>(wrapper); m_stringCache.set(stringImpl, m_lastV8String); m_lastStringImpl = stringImpl; return newString; }
v8::Handle<v8::String> StringCache::v8ExternalStringSlow(StringImpl* stringImpl, ReturnHandleType handleType, v8::Isolate* isolate) { if (!stringImpl->length()) return v8::String::Empty(isolate); v8::Persistent<v8::String> cachedV8String = m_stringCache.get(stringImpl); if (cachedV8String.IsWeak(isolate)) { m_lastStringImpl = stringImpl; m_lastV8String = cachedV8String; if (handleType == ReturnUnsafeHandle) return cachedV8String; return v8::Local<v8::String>::New(cachedV8String); } v8::Local<v8::String> newString = makeExternalString(String(stringImpl)); if (newString.IsEmpty()) return newString; v8::Persistent<v8::String> wrapper = v8::Persistent<v8::String>::New(isolate, newString); if (wrapper.IsEmpty()) return newString; stringImpl->ref(); wrapper.MarkIndependent(isolate); WeakHandleListener<StringCache, StringImpl>::makeWeak(isolate, wrapper, stringImpl); m_stringCache.set(stringImpl, wrapper); m_lastStringImpl = stringImpl; m_lastV8String = wrapper; return newString; }
v8::Local<v8::String> StringCache::createStringAndInsertIntoCache(v8::Isolate* isolate, StringImpl* stringImpl) { ASSERT(!m_stringCache.Contains(stringImpl)); ASSERT(stringImpl->length()); v8::Local<v8::String> newString = makeExternalString(String(stringImpl), isolate); ASSERT(!newString.IsEmpty()); ASSERT(newString->Length()); v8::UniquePersistent<v8::String> wrapper(isolate, newString); stringImpl->ref(); wrapper.MarkIndependent(); m_stringCache.Set(stringImpl, wrapper.Pass(), &m_lastV8String); m_lastStringImpl = stringImpl; return newString; }
v8::Local<v8::String> StringCache::createStringAndInsertIntoCache(StringImpl* stringImpl, v8::Isolate* isolate) { ASSERT(!m_stringCache.contains(stringImpl)); ASSERT(stringImpl->length()); v8::Local<v8::String> newString = makeExternalString(String(stringImpl), isolate); if (newString.IsEmpty()) return newString; v8::Persistent<v8::String> wrapper(isolate, newString); stringImpl->ref(); wrapper.MarkIndependent(); wrapper.SetWeak(stringImpl, &setWeakCallback); m_lastV8String = UnsafePersistent<v8::String>(wrapper); m_lastStringImpl = stringImpl; m_stringCache.set(stringImpl, m_lastV8String); return newString; }