diff options
Diffstat (limited to 'V8Binding/v8/v8_binding.cpp')
-rw-r--r-- | V8Binding/v8/v8_binding.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/V8Binding/v8/v8_binding.cpp b/V8Binding/v8/v8_binding.cpp new file mode 100644 index 0000000..3a36fc5 --- /dev/null +++ b/V8Binding/v8/v8_binding.cpp @@ -0,0 +1,120 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "v8_binding.h" + +#include "AtomicString.h" +#include "CString.h" +#include "MathExtras.h" +#include "PlatformString.h" +#include "StringBuffer.h" + +#include <v8.h> + +namespace WebCore { + +// WebCoreStringResource is a helper class for v8ExternalString. It is used +// to manage the life-cycle of the underlying buffer of the external string. +class WebCoreStringResource: public v8::String::ExternalStringResource { + public: + explicit WebCoreStringResource(const String& str) + : impl_(str.impl()) { } + + virtual ~WebCoreStringResource() {} + + const uint16_t* data() const { + return reinterpret_cast<const uint16_t*>(impl_.characters()); + } + + size_t length() const { return impl_.length(); } + + String webcore_string() { return impl_; } + + private: + // A shallow copy of the string. + // Keeps the string buffer alive until the V8 engine garbage collects it. + String impl_; +}; + +String v8StringToWebCoreString(v8::Handle<v8::String> v8_str) { + if (v8_str->IsExternal()) { + WebCoreStringResource* str_resource = static_cast<WebCoreStringResource*>( + v8_str->GetExternalStringResource()); + return str_resource->webcore_string(); + } + + int length = v8_str->Length(); + if (length == 0) { + // Avoid trying to morph empty strings, as they do not have enough room to + // contain the external reference. + return ""; + } + + // Copy the characters from the v8::String into a WebCore::String and allocate + // an external resource which will be attached to the v8::String. + String result; + const int kStringSizeToCopy = 256; + if (length < kStringSizeToCopy) { + uint16_t buffer[kStringSizeToCopy]; + v8_str->Write(buffer, 0, length); + result = StringImpl::create(reinterpret_cast<UChar*>(buffer), length); + } else { + StringBuffer buf(length); + v8_str->Write(reinterpret_cast<uint16_t*>(buf.characters()), 0, length); + result = String::adopt(buf); + } + +// +// TODO(mbelshe): Disable string morphing because it causes mystery +// perf regressions on intl1 and intl2 page cyclers. It works fine +// on machines other than the buildbots. +// +// WebCoreStringResource* resource = new WebCoreStringResource(result); +// if (!v8_str->MakeExternal(resource)) { +// // In case of a failure delete the external resource as it was not used. +// delete resource; +// } + return result; +} + + +String v8ValueToWebCoreString(v8::Handle<v8::Value> obj) { + v8::Handle<v8::String> v8_str; + if (obj->IsString()) { + v8_str = v8::Handle<v8::String>::Cast(obj); + } else { + v8::TryCatch block; + v8_str = obj->ToString(); + if (v8_str.IsEmpty()) + return ""; + } + return v8StringToWebCoreString(v8_str); +} + + +AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8_str) { + String str = v8StringToWebCoreString(v8_str); + return AtomicString(str); +} + + +AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> v8_str) { + String str = v8ValueToWebCoreString(v8_str); + return AtomicString(str); +} + + +v8::Handle<v8::String> v8String(const String& str) { + if (!str.length()) + return v8::String::Empty(); + return v8::String::NewExternal(new WebCoreStringResource(str)); +} + +v8::Local<v8::String> v8ExternalString(const String& str) { + if (!str.length()) + return v8::String::Empty(); + return v8::String::NewExternal(new WebCoreStringResource(str)); +} + +} // namespace WebCore |