diff options
author | japhet@chromium.org <japhet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-06 19:25:10 +0000 |
---|---|---|
committer | japhet@chromium.org <japhet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-06 19:25:10 +0000 |
commit | 82d27d8e9bef8f0a05d02f02ad07e43f44ae93be (patch) | |
tree | 981b72c507d0b323a5c97b158e8986f8c10454e6 /webkit/port | |
parent | 29a2e8d731c4d1206a2c11be246c28b5598cd982 (diff) | |
download | chromium_src-82d27d8e9bef8f0a05d02f02ad07e43f44ae93be.zip chromium_src-82d27d8e9bef8f0a05d02f02ad07e43f44ae93be.tar.gz chromium_src-82d27d8e9bef8f0a05d02f02ad07e43f44ae93be.tar.bz2 |
Reverting 19963.
Review URL: http://codereview.chromium.org/149208
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19968 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port')
-rw-r--r-- | webkit/port/bindings/v8/v8_binding.cpp | 130 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_binding.h | 135 |
2 files changed, 265 insertions, 0 deletions
diff --git a/webkit/port/bindings/v8/v8_binding.cpp b/webkit/port/bindings/v8/v8_binding.cpp new file mode 100644 index 0000000..616d7b2 --- /dev/null +++ b/webkit/port/bindings/v8/v8_binding.cpp @@ -0,0 +1,130 @@ +// 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, bool externalize) { + WebCoreStringResource* str_resource = static_cast<WebCoreStringResource*>( + v8_str->GetExternalStringResource()); + if (str_resource) { + 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 StringImpl::empty(); + } + + UChar* buffer; + String result = String::createUninitialized(length, buffer); + v8_str->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); + + if (externalize) { + 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) { + if (obj->IsString()) { + v8::Handle<v8::String> v8_str = v8::Handle<v8::String>::Cast(obj); + String webCoreString = v8StringToWebCoreString(v8_str, true); + return webCoreString; + } else if (obj->IsInt32()) { + int value = obj->Int32Value(); + // Most numbers used are <= 100. Even if they aren't used + // there's very little in using the space. + const int kLowNumbers = 100; + static AtomicString lowNumbers[kLowNumbers + 1]; + String webCoreString; + if (0 <= value && value <= kLowNumbers) { + webCoreString = lowNumbers[value]; + if (!webCoreString) { + AtomicString valueString = AtomicString(String::number(value)); + lowNumbers[value] = valueString; + webCoreString = valueString; + } + } else { + webCoreString = String::number(value); + } + return webCoreString; + } else { + v8::TryCatch block; + v8::Handle<v8::String> v8_str = obj->ToString(); + // Check for empty handles to handle the case where an exception + // is thrown as part of invoking toString on the object. + if (v8_str.IsEmpty()) + return StringImpl::empty(); + return v8StringToWebCoreString(v8_str, false); + } +} + + +AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8_str) { + String str = v8StringToWebCoreString(v8_str, true); + 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 diff --git a/webkit/port/bindings/v8/v8_binding.h b/webkit/port/bindings/v8/v8_binding.h new file mode 100644 index 0000000..2882026 --- /dev/null +++ b/webkit/port/bindings/v8/v8_binding.h @@ -0,0 +1,135 @@ +// 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. + +#ifndef V8_BINDING_H__ +#define V8_BINDING_H__ + +#include "config.h" + +#include "MathExtras.h" +#include "PlatformString.h" + +#include <v8.h> + +namespace WebCore { + +// The string returned by this function is still owned by the argument +// and will be deallocated when the argument is deallocated. +inline const uint16_t* FromWebCoreString(const String& str) { + return reinterpret_cast<const uint16_t*>(str.characters()); +} + +// Convert v8 types to a WebCore::String. If the V8 string is not already +// an external string then it is transformed into an external string at this +// point to avoid repeated conversions. +String v8StringToWebCoreString( + v8::Handle<v8::String> obj, bool externalize); +String v8ValueToWebCoreString(v8::Handle<v8::Value> obj); + +// TODO(mbelshe): drop this in favor of the type specific +// v8ValueToWebCoreString when we rework the code generation. +inline String ToWebCoreString(v8::Handle<v8::Value> obj) { + return v8ValueToWebCoreString(obj); +} + +inline String ToWebCoreString(v8::Handle<v8::String> string) { + return v8StringToWebCoreString(string, true); +} + +// Convert v8 types to a WebCore::AtomicString. +AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> obj); +AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> obj); + +inline String valueToStringWithNullCheck(v8::Handle<v8::Value> value) { + if (value->IsNull()) return String(); + return ToWebCoreString(value); +} + +inline String valueToStringWithNullOrUndefinedCheck( + v8::Handle<v8::Value> value) { + if (value->IsNull() || value->IsUndefined()) return String(); + return ToWebCoreString(value); +} + +// Convert a value to a 32-bit integer. The conversion fails if the +// value cannot be converted to an integer or converts to nan or to an +// infinity. +// FIXME: Rename to toInt32() once V8 bindings migration is complete. +inline int ToInt32(v8::Handle<v8::Value> value, bool& ok) { + ok = true; + + // Fast case. The value is already a 32-bit integer. + if (value->IsInt32()) { + return value->Int32Value(); + } + + // Can the value be converted to a number? + v8::Local<v8::Number> number_object = value->ToNumber(); + if (number_object.IsEmpty()) { + ok = false; + return 0; + } + + // Does the value convert to nan or to an infinity? + double number_value = number_object->Value(); + if (isnan(number_value) || isinf(number_value)) { + ok = false; + return 0; + } + + // Can the value be converted to a 32-bit integer? + v8::Local<v8::Int32> int_value = value->ToInt32(); + if (int_value.IsEmpty()) { + ok = false; + return 0; + } + + // Return the result of the int32 conversion. + return int_value->Value(); +} + +// Convert a value to a 32-bit integer assuming the conversion cannot fail. +// FIXME: Rename to toInt32() once V8 bindings migration is complete. +inline int ToInt32(v8::Handle<v8::Value> value) { + bool ok; + return ToInt32(value, ok); +} + +inline String ToString(const String& string) { + return string; +} + +// Convert a string to a V8 string. +v8::Handle<v8::String> v8String(const String& str); + +inline v8::Handle<v8::String> v8UndetectableString(const String& str) { + return v8::String::NewUndetectable(FromWebCoreString(str), str.length()); +} + +// Return a V8 external string that shares the underlying buffer with the given +// WebCore string. The reference counting mechanism is used to keep the +// underlying buffer alive while the string is still live in the V8 engine. +v8::Local<v8::String> v8ExternalString(const String& str); + +inline v8::Handle<v8::Value> v8StringOrNull(const String& str) { + return str.isNull() + ? v8::Handle<v8::Value>(v8::Null()) + : v8::Handle<v8::Value>(v8String(str)); +} + +inline v8::Handle<v8::Value> v8StringOrUndefined(const String& str) { + return str.isNull() + ? v8::Handle<v8::Value>(v8::Undefined()) + : v8::Handle<v8::Value>(v8String(str)); +} + +inline v8::Handle<v8::Value> v8StringOrFalse(const String& str) { + return str.isNull() + ? v8::Handle<v8::Value>(v8::False()) + : v8::Handle<v8::Value>(v8String(str)); +} + +} // namespace WebCore + +#endif // V8_BINDING_H__ |