[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
antonm at chromium.org
antonm at chromium.org
Wed Dec 22 12:51:34 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 189d25f2826c833d05cb240fcbff8e0475719a3b
Author: antonm at chromium.org <antonm at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Aug 31 19:35:21 2010 +0000
2010-08-31 Anton Muhin <antonm at chromium.org>
Reviewed by Adam Barth.
[v8] More correct and faster error handling when converting v8 objects to various WebCore strings
https://bugs.webkit.org/show_bug.cgi?id=44678
Split v8 object conversion into two phase: 1st, which can throw an exception, and
2nd, which must always succeed. That allows to report correctly the case when exception
happens.
* bindings/scripts/CodeGeneratorV8.pm:
* bindings/v8/V8Binding.cpp:
(WebCore::int32ToWebCoreString):
(WebCore::v8NonStringValueToWebCoreString):
* bindings/v8/V8Binding.h:
(WebCore::V8ParameterBase::operator String):
(WebCore::V8ParameterBase::operator AtomicString):
(WebCore::V8ParameterBase::V8ParameterBase):
(WebCore::V8ParameterBase::prepareBase):
(WebCore::V8ParameterBase::object):
(WebCore::V8ParameterBase::setString):
(WebCore::V8ParameterBase::toString):
(WebCore::):
(WebCore::::prepare):
* bindings/v8/custom/V8BindingMacros.h:
* bindings/v8/custom/V8DeviceMotionEventCustom.cpp:
(WebCore::V8DeviceMotionEvent::initDeviceMotionEventCallback):
* bindings/v8/cstom/V8DeviceOrientationEventCustom.cpp:
(WebCore::V8DeviceMotionEvent::initDeviceOrientationEventCallback):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66521 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3bd49db..3593155 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,34 @@
+2010-08-31 Anton Muhin <antonm at chromium.org>
+
+ Reviewed by Adam Barth.
+
+ [v8] More correct and faster error handling when converting v8 objects to various WebCore strings
+ https://bugs.webkit.org/show_bug.cgi?id=44678
+
+ Split v8 object conversion into two phase: 1st, which can throw an exception, and
+ 2nd, which must always succeed. That allows to report correctly the case when exception
+ happens.
+
+ * bindings/scripts/CodeGeneratorV8.pm:
+ * bindings/v8/V8Binding.cpp:
+ (WebCore::int32ToWebCoreString):
+ (WebCore::v8NonStringValueToWebCoreString):
+ * bindings/v8/V8Binding.h:
+ (WebCore::V8ParameterBase::operator String):
+ (WebCore::V8ParameterBase::operator AtomicString):
+ (WebCore::V8ParameterBase::V8ParameterBase):
+ (WebCore::V8ParameterBase::prepareBase):
+ (WebCore::V8ParameterBase::object):
+ (WebCore::V8ParameterBase::setString):
+ (WebCore::V8ParameterBase::toString):
+ (WebCore::):
+ (WebCore::::prepare):
+ * bindings/v8/custom/V8BindingMacros.h:
+ * bindings/v8/custom/V8DeviceMotionEventCustom.cpp:
+ (WebCore::V8DeviceMotionEvent::initDeviceMotionEventCallback):
+ * bindings/v8/cstom/V8DeviceOrientationEventCustom.cpp:
+ (WebCore::V8DeviceMotionEvent::initDeviceOrientationEventCallback):
+
2010-08-30 Ilya Tikhonovsky <loislo at chromium.org>
Reviewed by Joseph Pecoraro.
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index 56838ca..7357b7f 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -762,8 +762,11 @@ END
}
if ($useExceptions) {
- push(@implContentDecls, " $nativeType v = ");
- push(@implContentDecls, "$getterString;\n");
+ if ($nativeType =~ /^V8Parameter/) {
+ push(@implContentDecls, " " . ConvertToV8Parameter($attribute->signature, $nativeType, "v", $getterString) . ";\n");
+ } else {
+ push(@implContentDecls, " $nativeType v = $getterString;\n");
+ }
push(@implContentDecls, GenerateSetDOMException(" "));
$result = "v";
$result .= ".release()" if (IsRefPtrType($returnType));
@@ -830,6 +833,8 @@ sub GenerateNormalAttrSetter
my $implClassName = shift;
my $interfaceName = shift;
+ $implIncludes{"V8BindingMacros.h"} = 1;
+
my $attrExt = $attribute->signature->extendedAttributes;
my $conditionalString = GenerateConditionalString($attribute->signature);
@@ -890,7 +895,12 @@ END
push(@implContentDecls, " return;\n");
}
} else {
- push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
+ my $value = JSValueToNative($attribute->signature, "value");
+ if ($nativeType =~ /^V8Parameter/) {
+ push(@implContentDecls, " " . ConvertToV8Parameter($attribute->signature, $nativeType, "v", $value, "VOID") . "\n");
+ } else {
+ push(@implContentDecls, " $nativeType v = $value;\n");
+ }
}
my $result = "v";
@@ -1236,13 +1246,7 @@ END
push(@implContentDecls, " }\n");
} elsif ($nativeType =~ /^V8Parameter/) {
my $value = JSValueToNative($parameter, "args[$paramIndex]", BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef);
- if ($parameter->type eq "DOMString") {
- $implIncludes{"V8BindingMacros.h"} = 1;
- push(@implContentDecls, " STRING_TO_V8PARAMETER_EXCEPTION_BLOCK($nativeType, $parameterName, $value);\n");
- } else {
- # Don't know how to properly check for conversion exceptions when $parameter->type is "DOMUserData"
- push(@implContentDecls, " $nativeType $parameterName = $value;\n");
- }
+ push(@implContentDecls, " " . ConvertToV8Parameter($parameter, $nativeType, $parameterName, $value) . "\n");
} else {
$implIncludes{"V8BindingMacros.h"} = 1;
# For functions with "StrictTypeChecking", if an input parameter's type does not match the signature,
@@ -3316,6 +3320,25 @@ sub GetCallbackClassName
return "V8$interfaceName";
}
+sub ConvertToV8Parameter
+{
+ my $signature = shift;
+ my $nativeType = shift;
+ my $variableName = shift;
+ my $value = shift;
+ my $suffix = shift;
+
+ die "Wrong native type passed: $nativeType" unless $nativeType =~ /^V8Parameter/;
+ if ($signature->type eq "DOMString") {
+ my $macro = "STRING_TO_V8PARAMETER_EXCEPTION_BLOCK";
+ $macro .= "_$suffix" if $suffix;
+ return "$macro($nativeType, $variableName, $value);"
+ } else {
+ # Don't know how to properly check for conversion exceptions when $parameter->type is "DOMUserData"
+ return "$nativeType $variableName($value, true);";
+ }
+}
+
sub DebugPrint
{
my $output = shift;
diff --git a/WebCore/bindings/v8/V8Binding.cpp b/WebCore/bindings/v8/V8Binding.cpp
index 3799cdb..734e07b 100644
--- a/WebCore/bindings/v8/V8Binding.cpp
+++ b/WebCore/bindings/v8/V8Binding.cpp
@@ -368,27 +368,33 @@ StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode
template String v8StringToWebCoreString<String>(v8::Handle<v8::String>, ExternalMode);
template AtomicString v8StringToWebCoreString<AtomicString>(v8::Handle<v8::String>, ExternalMode);
+String int32ToWebCoreString(int value)
+{
+ // Caching of small strings below is not thread safe: newly constructed AtomicString
+ // are not safely published.
+ ASSERT(WTF::isMainThread());
+
+ // Most numbers used are <= 100. Even if they aren't used there's very little cost 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;
+}
String v8NonStringValueToWebCoreString(v8::Handle<v8::Value> object)
{
ASSERT(!object->IsString());
- if (object->IsInt32()) {
- int value = object->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;
- }
+ if (object->IsInt32())
+ return int32ToWebCoreString(object->Int32Value());
v8::TryCatch block;
v8::Handle<v8::String> v8String = object->ToString();
diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h
index 087c128..58989ed 100644
--- a/WebCore/bindings/v8/V8Binding.h
+++ b/WebCore/bindings/v8/V8Binding.h
@@ -210,6 +210,61 @@ namespace WebCore {
v8::Persistent<v8::String> getToStringName();
v8::Persistent<v8::FunctionTemplate> getToStringTemplate();
+ String int32ToWebCoreString(int value);
+
+ class V8ParameterBase {
+ public:
+ operator String() { return toString<String>(); }
+ operator AtomicString() { return toString<AtomicString>(); }
+
+ protected:
+ V8ParameterBase(v8::Local<v8::Value> object) : m_v8Object(object), m_mode(Externalize), m_string() { }
+
+ bool prepareBase()
+ {
+ if (LIKELY(m_v8Object->IsString()))
+ return true;
+
+ if (LIKELY(m_v8Object->IsInt32())) {
+ setString(int32ToWebCoreString(m_v8Object->Int32Value()));
+ return true;
+ }
+
+ m_mode = DoNotExternalize;
+ v8::TryCatch block;
+ m_v8Object = m_v8Object->ToString();
+ // Handle the case where an exception is thrown as part of invoking toString on the object.
+ if (block.HasCaught()) {
+ block.ReThrow();
+ return false;
+ }
+
+ return true;
+ }
+
+ v8::Local<v8::Value> object() { return m_v8Object; }
+
+ void setString(String string)
+ {
+ m_string = string;
+ m_v8Object.Clear(); // To signal that String is ready.
+ }
+
+ private:
+ v8::Local<v8::Value> m_v8Object;
+ ExternalMode m_mode;
+ String m_string;
+
+ template <class StringType>
+ StringType toString()
+ {
+ if (LIKELY(!m_v8Object.IsEmpty()))
+ return v8StringToWebCoreString<StringType>(m_v8Object.As<v8::String>(), m_mode);
+
+ return StringType(m_string);
+ }
+ };
+
// V8Parameter is an adapter class that converts V8 values to Strings
// or AtomicStrings as appropriate, using multiple typecast operators.
enum V8ParameterMode {
@@ -218,22 +273,38 @@ namespace WebCore {
WithUndefinedOrNullCheck
};
template <V8ParameterMode MODE = DefaultMode>
- class V8Parameter {
+ class V8Parameter: public V8ParameterBase {
public:
- V8Parameter(v8::Local<v8::Value> object = v8::Local<v8::Value>()) : m_v8Object(object) { }
- operator String();
- operator AtomicString();
- private:
- v8::Local<v8::Value> m_v8Object;
+ V8Parameter(v8::Local<v8::Value> object) : V8ParameterBase(object) { }
+ V8Parameter(v8::Local<v8::Value> object, bool) : V8ParameterBase(object) { prepare(); }
+
+ bool prepare();
};
- template<> inline V8Parameter<DefaultMode>::operator String() { return toWebCoreString(m_v8Object); }
- template<> inline V8Parameter<WithNullCheck>::operator String() { return toWebCoreStringWithNullCheck(m_v8Object); }
- template<> inline V8Parameter<WithUndefinedOrNullCheck>::operator String() { return toWebCoreStringWithNullOrUndefinedCheck(m_v8Object); }
+ template<> inline bool V8Parameter<DefaultMode>::prepare()
+ {
+ return V8ParameterBase::prepareBase();
+ }
+
+ template<> inline bool V8Parameter<WithNullCheck>::prepare()
+ {
+ if (object()->IsNull()) {
+ setString(String());
+ return true;
+ }
- template<> inline V8Parameter<DefaultMode>::operator AtomicString() { return v8ValueToAtomicWebCoreString(m_v8Object); }
- template<> inline V8Parameter<WithNullCheck>::operator AtomicString() { return toAtomicWebCoreStringWithNullCheck(m_v8Object); }
- template<> inline V8Parameter<WithUndefinedOrNullCheck>::operator AtomicString() { return toAtomicWebCoreStringWithNullCheck(m_v8Object); }
+ return V8ParameterBase::prepareBase();
+ }
+
+ template<> inline bool V8Parameter<WithUndefinedOrNullCheck>::prepare()
+ {
+ if (object()->IsNull() || object()->IsUndefined()) {
+ setString(String());
+ return true;
+ }
+
+ return V8ParameterBase::prepareBase();
+ }
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8BindingMacros.h b/WebCore/bindings/v8/custom/V8BindingMacros.h
index b569b10..ad02c3e 100644
--- a/WebCore/bindings/v8/custom/V8BindingMacros.h
+++ b/WebCore/bindings/v8/custom/V8BindingMacros.h
@@ -38,12 +38,11 @@
}
#define STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(type, var, value) \
- type var; \
- { \
- v8::Local<v8::Value> v8Value = (value); \
- v8::TryCatch block; \
- (value)->ToString(); \
- if (block.HasCaught()) \
- return block.ReThrow(); \
- var = v8Value; \
- }
+ type var(value); \
+ if (!var.prepare()) \
+ return v8::Undefined();
+
+#define STRING_TO_V8PARAMETER_EXCEPTION_BLOCK_VOID(type, var, value) \
+ type var(value); \
+ if (!var.prepare()) \
+ return;
diff --git a/WebCore/bindings/v8/custom/V8DeviceMotionEventCustom.cpp b/WebCore/bindings/v8/custom/V8DeviceMotionEventCustom.cpp
index 39692b6..67f27c5 100644
--- a/WebCore/bindings/v8/custom/V8DeviceMotionEventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DeviceMotionEventCustom.cpp
@@ -30,6 +30,7 @@
#include "DeviceMotionData.h"
#include "V8Binding.h"
+#include "V8BindingMacros.h"
#include "V8Proxy.h"
#include <v8.h>
@@ -110,7 +111,7 @@ v8::Handle<v8::Value> V8DeviceMotionEvent::intervalAccessorGetter(v8::Local<v8::
v8::Handle<v8::Value> V8DeviceMotionEvent::initDeviceMotionEventCallback(const v8::Arguments& args)
{
DeviceMotionEvent* imp = V8DeviceMotionEvent::toNative(args.Holder());
- V8Parameter<> type = args[0];
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, type, args[0]);
bool bubbles = args[1]->BooleanValue();
bool cancelable = args[2]->BooleanValue();
// If any of the parameters are null or undefined, mark them as not provided.
diff --git a/WebCore/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp b/WebCore/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp
index 26cc6cc..0fee4d1 100644
--- a/WebCore/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DeviceOrientationEventCustom.cpp
@@ -69,7 +69,7 @@ v8::Handle<v8::Value> V8DeviceOrientationEvent::gammaAccessorGetter(v8::Local<v8
v8::Handle<v8::Value> V8DeviceOrientationEvent::initDeviceOrientationEventCallback(const v8::Arguments& args)
{
DeviceOrientationEvent* imp = V8DeviceOrientationEvent::toNative(args.Holder());
- V8Parameter<> type = args[0];
+ STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, type, args[0]);
bool bubbles = args[1]->BooleanValue();
bool cancelable = args[2]->BooleanValue();
// If alpha, beta or gamma are null or undefined, mark them as not provided.
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list