summaryrefslogtreecommitdiffstats
path: root/V8Binding
diff options
context:
space:
mode:
authorFeng Qian <fqian@google.com>2009-04-29 13:44:39 -0700
committerFeng Qian <fqian@google.com>2009-04-29 14:03:16 -0700
commit25f03f86220d0b28648f70eceb4ba64821552001 (patch)
tree93d9905c532d5f0fda746331ca8cff142f46cbbd /V8Binding
parent8535e17115184dbb5e448b6364b88eb52df34482 (diff)
parent5001a3bfb57dd395bf6774dd1223042b0c03afa7 (diff)
downloadexternal_webkit-25f03f86220d0b28648f70eceb4ba64821552001.zip
external_webkit-25f03f86220d0b28648f70eceb4ba64821552001.tar.gz
external_webkit-25f03f86220d0b28648f70eceb4ba64821552001.tar.bz2
Merge commit 'goog/master-v8droid' into HEAD
The CL imports V8 source from trunk, and V8 binding code from Chromium, and small changes from future WebKit revision. To enable V8, add ENABLE_V8 := true in buildspec.mk.
Diffstat (limited to 'V8Binding')
-rw-r--r--V8Binding/CHROME_REVISION1
-rw-r--r--V8Binding/DerivedSources.make1185
-rw-r--r--V8Binding/V8Binding.derived.mk431
-rw-r--r--V8Binding/jni/jni_class.cpp146
-rw-r--r--V8Binding/jni/jni_class.h53
-rw-r--r--V8Binding/jni/jni_instance.cpp228
-rw-r--r--V8Binding/jni/jni_instance.h89
-rw-r--r--V8Binding/jni/jni_npobject.cpp46
-rw-r--r--V8Binding/jni/jni_npobject.h27
-rw-r--r--V8Binding/jni/jni_runtime.cpp169
-rw-r--r--V8Binding/jni/jni_runtime.h124
-rw-r--r--V8Binding/jni/jni_utility.cpp474
-rw-r--r--V8Binding/jni/jni_utility.h281
-rw-r--r--V8Binding/npapi/README3
-rw-r--r--V8Binding/npapi/npapi.h853
-rw-r--r--V8Binding/npapi/npruntime.h357
-rw-r--r--V8Binding/scripts/CodeGenerator.pm334
-rw-r--r--V8Binding/scripts/CodeGeneratorV8.pm2181
-rw-r--r--V8Binding/scripts/IDLParser.pm441
-rw-r--r--V8Binding/scripts/generate-bindings.pl69
-rw-r--r--V8Binding/v8/DOMObjectsInclude.h191
-rw-r--r--V8Binding/v8/JSDOMBinding.cpp52
-rw-r--r--V8Binding/v8/JSDOMBinding.h50
-rw-r--r--V8Binding/v8/JSXPathNSResolver.cpp90
-rw-r--r--V8Binding/v8/JSXPathNSResolver.h33
-rw-r--r--V8Binding/v8/NPV8Object.cpp504
-rw-r--r--V8Binding/v8/NPV8Object.h41
-rw-r--r--V8Binding/v8/RGBColor.cpp50
-rw-r--r--V8Binding/v8/RGBColor.h28
-rw-r--r--V8Binding/v8/ScriptController.cpp446
-rw-r--r--V8Binding/v8/ScriptController.h271
-rw-r--r--V8Binding/v8/UndetectableHTMLCollection.idl14
-rw-r--r--V8Binding/v8/V8CanvasPixelArrayCustom.cpp77
-rw-r--r--V8Binding/v8/V8InitializeThreading.cpp44
-rw-r--r--V8Binding/v8/V8InitializeThreading.h39
-rw-r--r--V8Binding/v8/V8MessagePortCustom.cpp239
-rw-r--r--V8Binding/v8/V8NPObject.cpp369
-rw-r--r--V8Binding/v8/V8NPObject.h57
-rw-r--r--V8Binding/v8/V8NPUtils.cpp124
-rw-r--r--V8Binding/v8/V8NPUtils.h31
-rw-r--r--V8Binding/v8/V8SVGPODTypeWrapper.h363
-rw-r--r--V8Binding/v8/V8WorkerContextCustom.cpp230
-rw-r--r--V8Binding/v8/V8WorkerCustom.cpp282
-rw-r--r--V8Binding/v8/dom_wrapper_map.h72
-rw-r--r--V8Binding/v8/npruntime.cpp418
-rw-r--r--V8Binding/v8/npruntime_impl.h69
-rw-r--r--V8Binding/v8/npruntime_internal.h41
-rw-r--r--V8Binding/v8/npruntime_priv.h95
-rw-r--r--V8Binding/v8/v8_binding.cpp120
-rw-r--r--V8Binding/v8/v8_binding.h130
-rw-r--r--V8Binding/v8/v8_custom.cpp1102
-rw-r--r--V8Binding/v8/v8_custom.h545
-rw-r--r--V8Binding/v8/v8_helpers.cpp59
-rw-r--r--V8Binding/v8/v8_helpers.h29
-rw-r--r--V8Binding/v8/v8_index.cpp424
-rw-r--r--V8Binding/v8/v8_index.h510
-rw-r--r--V8Binding/v8/v8_npobject.h7
-rw-r--r--V8Binding/v8/v8_proxy.cpp3392
-rw-r--r--V8Binding/v8/v8_proxy.h645
-rw-r--r--V8Binding/v8/v8_utility.h58
60 files changed, 18833 insertions, 0 deletions
diff --git a/V8Binding/CHROME_REVISION b/V8Binding/CHROME_REVISION
new file mode 100644
index 0000000..584e140
--- /dev/null
+++ b/V8Binding/CHROME_REVISION
@@ -0,0 +1 @@
+svn://chrome-svn/chrome/trunk/src@12771
diff --git a/V8Binding/DerivedSources.make b/V8Binding/DerivedSources.make
new file mode 100644
index 0000000..227aa5e
--- /dev/null
+++ b/V8Binding/DerivedSources.make
@@ -0,0 +1,1185 @@
+# Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+# its contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+VPATH = \
+ $(PORTROOT)/bindings/v8 \
+ $(WebCore) \
+ $(WebCore)/bindings/js \
+ $(WebCore)/bindings/v8 \
+ $(WebCore)/bindings/objc \
+ $(WebCore)/css \
+ $(WebCore)/dom \
+ $(WebCore)/html \
+ $(WebCore)/inspector \
+ $(WebCore)/page \
+ $(WebCore)/plugins \
+ $(WebCore)/storage \
+ $(WebCore)/xml \
+ $(WebCore)/workers \
+ $(WebCore)/svg \
+#
+
+.PHONY : all
+
+ifeq ($(OS),MACOS)
+all : \
+ CharsetData.cpp
+endif
+
+# Not needed because we don't want obj-c bindings generated
+# DOMAbstractView.h\
+ DOMAttr.h \
+ DOMCDATASection.h \
+ DOMCSSCharsetRule.h \
+ DOMCSSFontFaceRule.h \
+ DOMCSSImportRule.h \
+ DOMCSSMediaRule.h \
+ DOMCSSPageRule.h \
+ DOMCSSPrimitiveValue.h \
+ DOMCSSRule.h \
+ DOMCSSRuleList.h \
+ DOMCSSStyleDeclaration.h \
+ DOMCSSStyleRule.h \
+ DOMCSSStyleSheet.h \
+ DOMCSSUnknownRule.h \
+ DOMCSSValue.h \
+ DOMCSSValueList.h \
+ DOMCharacterData.h \
+ DOMComment.h \
+ DOMCounter.h \
+ DOMDOMImplementation.h \
+ DOMDocument.h \
+ DOMDocumentFragment.h \
+ DOMDocumentType.h \
+ DOMElement.h \
+ DOMEntity.h \
+ DOMEntityReference.h \
+ DOMEvent.h \
+ DOMEventListener.h \
+ DOMEventTarget.h \
+ DOMHTMLAnchorElement.h \
+ DOMHTMLAppletElement.h \
+ DOMHTMLAreaElement.h \
+ DOMHTMLBRElement.h \
+ DOMHTMLBaseElement.h \
+ DOMHTMLBaseFontElement.h \
+ DOMHTMLBodyElement.h \
+ DOMHTMLButtonElement.h \
+ DOMHTMLCanvasElement.h \
+ DOMHTMLCollection.h \
+ DOMHTMLDListElement.h \
+ DOMHTMLDirectoryElement.h \
+ DOMHTMLDivElement.h \
+ DOMHTMLDocument.h \
+ DOMHTMLElement.h \
+ DOMHTMLEmbedElement.h \
+ DOMHTMLFieldSetElement.h \
+ DOMHTMLFontElement.h \
+ DOMHTMLFormElement.h \
+ DOMHTMLFrameElement.h \
+ DOMHTMLFrameSetElement.h \
+ DOMHTMLHRElement.h \
+ DOMHTMLHeadElement.h \
+ DOMHTMLHeadingElement.h \
+ DOMHTMLHtmlElement.h \
+ DOMHTMLIFrameElement.h \
+ DOMHTMLImageElement.h \
+ DOMHTMLInputElement.h \
+ DOMHTMLIsIndexElement.h \
+ DOMHTMLLIElement.h \
+ DOMHTMLLabelElement.h \
+ DOMHTMLLegendElement.h \
+ DOMHTMLLinkElement.h \
+ DOMHTMLMapElement.h \
+ DOMHTMLMarqueeElement.h \
+ DOMHTMLMenuElement.h \
+ DOMHTMLMetaElement.h \
+ DOMHTMLModElement.h \
+ DOMHTMLOListElement.h \
+ DOMHTMLObjectElement.h \
+ DOMHTMLOptGroupElement.h \
+ DOMHTMLOptionElement.h \
+ DOMHTMLOptionsCollection.h \
+ DOMHTMLParagraphElement.h \
+ DOMHTMLParamElement.h \
+ DOMHTMLPreElement.h \
+ DOMHTMLQuoteElement.h \
+ DOMHTMLScriptElement.h \
+ DOMHTMLSelectElement.h \
+ DOMHTMLStyleElement.h \
+ DOMHTMLTableCaptionElement.h \
+ DOMHTMLTableCellElement.h \
+ DOMHTMLTableColElement.h \
+ DOMHTMLTableElement.h \
+ DOMHTMLTableRowElement.h \
+ DOMHTMLTableSectionElement.h \
+ DOMHTMLTextAreaElement.h \
+ DOMHTMLTitleElement.h \
+ DOMHTMLUListElement.h \
+ DOMKeyboardEvent.h \
+ DOMMessageEvent.h \
+ DOMMediaList.h \
+ DOMMouseEvent.h \
+ DOMMutationEvent.h \
+ DOMNamedNodeMap.h \
+ DOMNode.h \
+ DOMNodeFilter.h \
+ DOMNodeIterator.h \
+ DOMNodeList.h \
+ DOMNotation.h \
+ DOMOverflowEvent.h \
+ DOMProcessingInstruction.h \
+ DOMRGBColor.h \
+ DOMRange.h \
+ DOMRect.h \
+ DOMSVGAElement.h \
+ DOMSVGAngle.h \
+ DOMSVGAnimateColorElement.h \
+ DOMSVGAnimateElement.h \
+ DOMSVGAnimateTransformElement.h \
+ DOMSVGAnimatedAngle.h \
+ DOMSVGAnimatedBoolean.h \
+ DOMSVGAnimatedEnumeration.h \
+ DOMSVGAnimatedInteger.h \
+ DOMSVGAnimatedLength.h \
+ DOMSVGAnimatedLengthList.h \
+ DOMSVGAnimatedNumber.h \
+ DOMSVGAnimatedNumberList.h \
+ DOMSVGAnimatedPathData.h \
+ DOMSVGAnimatedPoints.h \
+ DOMSVGAnimatedPreserveAspectRatio.h \
+ DOMSVGAnimatedRect.h \
+ DOMSVGAnimatedString.h \
+ DOMSVGAnimatedTransformList.h \
+ DOMSVGAnimationElement.h \
+ DOMSVGCircleElement.h \
+ DOMSVGClipPathElement.h \
+ DOMSVGColor.h \
+ DOMSVGComponentTransferFunctionElement.h \
+ DOMSVGCursorElement.h \
+ DOMSVGDefinitionSrcElement.h \
+ DOMSVGDefsElement.h \
+ DOMSVGDescElement.h \
+ DOMSVGDocument.h \
+ DOMSVGElement.h \
+ DOMSVGElementInstance.h \
+ DOMSVGElementInstanceList.h \
+ DOMSVGEllipseElement.h \
+ DOMSVGExternalResourcesRequired.h \
+ DOMSVGFEBlendElement.h \
+ DOMSVGFEColorMatrixElement.h \
+ DOMSVGFEComponentTransferElement.h \
+ DOMSVGFECompositeElement.h \
+ DOMSVGFEDiffuseLightingElement.h \
+ DOMSVGFEDisplacementMapElement.h \
+ DOMSVGFEDistantLightElement.h \
+ DOMSVGFEFloodElement.h \
+ DOMSVGFEFuncAElement.h \
+ DOMSVGFEFuncBElement.h \
+ DOMSVGFEFuncGElement.h \
+ DOMSVGFEFuncRElement.h \
+ DOMSVGFEGaussianBlurElement.h \
+ DOMSVGFEImageElement.h \
+ DOMSVGFEMergeElement.h \
+ DOMSVGFEMergeNodeElement.h \
+ DOMSVGFEOffsetElement.h \
+ DOMSVGFEPointLightElement.h \
+ DOMSVGFESpecularLightingElement.h \
+ DOMSVGFESpotLightElement.h \
+ DOMSVGFETileElement.h \
+ DOMSVGFETurbulenceElement.h \
+ DOMSVGFontElement.h \
+ DOMSVGFontFaceElement.h \
+ DOMSVGFontFaceFormatElement.h \
+ DOMSVGFontFaceNameElement.h \
+ DOMSVGFontFaceSrcElement.h \
+ DOMSVGFontFaceUriElement.h \
+ DOMSVGFilterElement.h \
+ DOMSVGFilterPrimitiveStandardAttributes.h \
+ DOMSVGFitToViewBox.h \
+ DOMSVGForeignObjectElement.h \
+ DOMSVGGElement.h \
+ DOMSVGGlyphElement.h \
+ DOMSVGGradientElement.h \
+ DOMSVGImageElement.h \
+ DOMSVGLangSpace.h \
+ DOMSVGLength.h \
+ DOMSVGLengthList.h \
+ DOMSVGLineElement.h \
+ DOMSVGLinearGradientElement.h \
+ DOMSVGLocatable.h \
+ DOMSVGMarkerElement.h \
+ DOMSVGMaskElement.h \
+ DOMSVGMatrix.h \
+ DOMSVGMetadataElement.h \
+ DOMSVGMissingGlyphElement.h \
+ DOMSVGNumber.h \
+ DOMSVGNumberList.h \
+ DOMSVGPaint.h \
+ DOMSVGPathElement.h \
+ DOMSVGPathSeg.h \
+ DOMSVGPathSegArcAbs.h \
+ DOMSVGPathSegArcRel.h \
+ DOMSVGPathSegClosePath.h \
+ DOMSVGPathSegCurvetoCubicAbs.h \
+ DOMSVGPathSegCurvetoCubicRel.h \
+ DOMSVGPathSegCurvetoCubicSmoothAbs.h \
+ DOMSVGPathSegCurvetoCubicSmoothRel.h \
+ DOMSVGPathSegCurvetoQuadraticAbs.h \
+ DOMSVGPathSegCurvetoQuadraticRel.h \
+ DOMSVGPathSegCurvetoQuadraticSmoothAbs.h \
+ DOMSVGPathSegCurvetoQuadraticSmoothRel.h \
+ DOMSVGPathSegLinetoAbs.h \
+ DOMSVGPathSegLinetoHorizontalAbs.h \
+ DOMSVGPathSegLinetoHorizontalRel.h \
+ DOMSVGPathSegLinetoRel.h \
+ DOMSVGPathSegLinetoVerticalAbs.h \
+ DOMSVGPathSegLinetoVerticalRel.h \
+ DOMSVGPathSegList.h \
+ DOMSVGPathSegMovetoAbs.h \
+ DOMSVGPathSegMovetoRel.h \
+ DOMSVGPatternElement.h \
+ DOMSVGPoint.h \
+ DOMSVGPointList.h \
+ DOMSVGPolygonElement.h \
+ DOMSVGPolylineElement.h \
+ DOMSVGPreserveAspectRatio.h \
+ DOMSVGRadialGradientElement.h \
+ DOMSVGRect.h \
+ DOMSVGRectElement.h \
+ DOMSVGRenderingIntent.h \
+ DOMSVGSVGElement.h \
+ DOMSVGScriptElement.h \
+ DOMSVGSetElement.h \
+ DOMSVGStopElement.h \
+ DOMSVGStringList.h \
+ DOMSVGStylable.h \
+ DOMSVGStyleElement.h \
+ DOMSVGSwitchElement.h \
+ DOMSVGSymbolElement.h \
+ DOMSVGTRefElement.h \
+ DOMSVGTSpanElement.h \
+ DOMSVGTests.h \
+ DOMSVGTextContentElement.h \
+ DOMSVGTextElement.h \
+ DOMSVGTextPathElement.h \
+ DOMSVGTextPositioningElement.h \
+ DOMSVGTitleElement.h \
+ DOMSVGTransform.h \
+ DOMSVGTransformList.h \
+ DOMSVGTransformable.h \
+ DOMSVGURIReference.h \
+ DOMSVGUnitTypes.h \
+ DOMSVGUseElement.h \
+ DOMSVGViewElement.h \
+ DOMSVGZoomAndPan.h \
+ DOMSVGZoomEvent.h \
+ DOMStyleSheet.h \
+ DOMStyleSheetList.h \
+ DOMText.h \
+ DOMTextEvent.h \
+ DOMTreeWalker.h \
+ DOMUIEvent.h \
+ DOMWheelEvent.h \
+ DOMXPathExpression.h \
+ DOMXPathNSResolver.h \
+ DOMXPathResult.h \
+endif
+
+# Not needed for V8\
+all : \
+ CSSGrammar.cpp \
+ CSSPropertyNames.h \
+ CSSValueKeywords.h \
+ ColorData.c \
+ DocTypeStrings.cpp \
+ HTMLEntityNames.c \
+ JSAttr.h \
+ JSBarInfo.h \
+ JSCDATASection.h \
+ JSCSSCharsetRule.h \
+ JSCSSFontFaceRule.h \
+ JSCSSImportRule.h \
+ JSCSSMediaRule.h \
+ JSCSSPageRule.h \
+ JSCSSPrimitiveValue.h \
+ JSCSSRule.h \
+ JSCSSRuleList.h \
+ JSCSSStyleRule.h \
+ JSCSSStyleSheet.h \
+ JSCSSValue.h \
+ JSCSSValueList.h \
+ JSCanvasGradient.h \
+ JSCanvasPattern.h \
+ JSCanvasRenderingContext2D.h \
+ JSCharacterData.h \
+ JSComment.h \
+ JSConsole.h \
+ JSCounter.h \
+ JSCSSStyleDeclaration.h \
+ JSDOMCoreException.h \
+ JSDOMImplementation.h \
+ JSDOMParser.h \
+ JSDOMSelection.h \
+ JSDOMWindow.h \
+ JSDatabase.h \
+ JSDocument.h \
+ JSDocumentFragment.h \
+ JSDocumentType.h \
+ JSElement.h \
+ JSEntity.h \
+ JSEntityReference.h \
+ JSEvent.h \
+ JSEventException.h \
+ JSEventTargetBase.lut.h \
+ JSHTMLAnchorElement.h \
+ JSHTMLAppletElement.h \
+ JSHTMLAreaElement.h \
+ JSHTMLAudioElement.h \
+ JSHTMLBaseElement.h \
+ JSHTMLBaseFontElement.h \
+ JSHTMLBlockquoteElement.h \
+ JSHTMLBodyElement.h \
+ JSHTMLBRElement.h \
+ JSHTMLButtonElement.h \
+ JSHTMLCanvasElement.h \
+ JSHTMLCollection.h \
+ JSHTMLDListElement.h \
+ JSHTMLDirectoryElement.h \
+ JSHTMLDivElement.h \
+ JSHTMLDocument.h \
+ JSHTMLElement.h \
+ JSHTMLEmbedElement.h \
+ JSHTMLFieldSetElement.h \
+ JSHTMLFontElement.h \
+ JSHTMLFormElement.h \
+ JSHTMLFrameElement.h \
+ JSHTMLFrameSetElement.h \
+ JSHTMLHRElement.h \
+ JSHTMLHeadElement.h \
+ JSHTMLHeadingElement.h \
+ JSHTMLHtmlElement.h \
+ JSHTMLIFrameElement.h \
+ JSHTMLImageElement.h \
+ JSHTMLInputElement.h \
+ JSHTMLInputElementBaseTable.cpp \
+ JSHTMLIsIndexElement.h \
+ JSHTMLLIElement.h \
+ JSHTMLLabelElement.h \
+ JSHTMLLegendElement.h \
+ JSHTMLLinkElement.h \
+ JSHTMLMapElement.h \
+ JSHTMLMarqueeElement.h \
+ JSHTMLMediaElement.h \
+ JSHTMLMenuElement.h \
+ JSHTMLMetaElement.h \
+ JSHTMLModElement.h \
+ JSHTMLOListElement.h \
+ JSHTMLOptGroupElement.h \
+ JSHTMLObjectElement.h \
+ JSHTMLOptionElement.h \
+ JSHTMLOptionsCollection.h \
+ JSHTMLParagraphElement.h \
+ JSHTMLParamElement.h \
+ JSHTMLPreElement.h \
+ JSHTMLQuoteElement.h \
+ JSHTMLScriptElement.h \
+ JSHTMLSelectElement.h \
+ JSHTMLSourceElement.h \
+ JSHTMLStyleElement.h \
+ JSHTMLTableCaptionElement.h \
+ JSHTMLTableCellElement.h \
+ JSHTMLTableColElement.h \
+ JSHTMLTableElement.h \
+ JSHTMLTableRowElement.h \
+ JSHTMLTableSectionElement.h \
+ JSHTMLTextAreaElement.h \
+ JSHTMLTitleElement.h \
+ JSHTMLUListElement.h \
+ JSHTMLVideoElement.h \
+ JSHistory.h \
+ JSKeyboardEvent.h \
+ JSLocation.lut.h \
+ JSMediaError.h \
+ JSMediaList.h \
+ JSMessageEvent.h \
+ JSMouseEvent.h \
+ JSMutationEvent.h \
+ JSNamedNodeMap.h \
+ JSNode.h \
+ JSNodeFilter.h \
+ JSNodeIterator.h \
+ JSNodeList.h \
+ JSNotation.h \
+ JSOverflowEvent.h \
+ JSProcessingInstruction.h \
+ JSProgressEvent.h \
+ JSRange.h \
+ JSRangeException.h \
+ JSRect.h \
+ JSSQLError.h \
+ JSSQLResultSet.h \
+ JSSQLResultSetRowList.h \
+ JSSQLTransaction.h \
+ JSSVGAElement.h \
+ JSSVGAngle.h \
+ JSSVGAnimatedAngle.h \
+ JSSVGAnimateColorElement.h \
+ JSSVGAnimateElement.h \
+ JSSVGAnimateTransformElement.h \
+ JSSVGAnimatedBoolean.h \
+ JSSVGAnimatedEnumeration.h \
+ JSSVGAnimatedInteger.h \
+ JSSVGAnimatedLength.h \
+ JSSVGAnimatedLengthList.h \
+ JSSVGAnimatedNumber.h \
+ JSSVGAnimatedNumberList.h \
+ JSSVGAnimatedPreserveAspectRatio.h \
+ JSSVGAnimatedRect.h \
+ JSSVGAnimatedString.h \
+ JSSVGAnimatedTransformList.h \
+ JSSVGAnimationElement.h \
+ JSSVGColor.h \
+ JSSVGCircleElement.h \
+ JSSVGClipPathElement.h \
+ JSSVGComponentTransferFunctionElement.h \
+ JSSVGCursorElement.h \
+ JSSVGDefsElement.h \
+ JSSVGDefinitionSrcElement.h \
+ JSSVGDescElement.h \
+ JSSVGDocument.h \
+ JSSVGException.h \
+ JSSVGLength.h \
+ JSSVGMatrix.h \
+ JSSVGMetadataElement.h \
+ JSSVGPathElement.h \
+ JSSVGPathSeg.h \
+ JSSVGPathSegArcAbs.h \
+ JSSVGPathSegArcRel.h \
+ JSSVGPathSegClosePath.h \
+ JSSVGPathSegCurvetoCubicAbs.h \
+ JSSVGPathSegCurvetoCubicRel.h \
+ JSSVGPathSegCurvetoCubicSmoothAbs.h \
+ JSSVGPathSegCurvetoCubicSmoothRel.h \
+ JSSVGPathSegCurvetoQuadraticAbs.h \
+ JSSVGPathSegCurvetoQuadraticRel.h \
+ JSSVGPathSegCurvetoQuadraticSmoothAbs.h \
+ JSSVGPathSegCurvetoQuadraticSmoothRel.h \
+ JSSVGPathSegLinetoAbs.h \
+ JSSVGPathSegLinetoHorizontalAbs.h \
+ JSSVGPathSegLinetoHorizontalRel.h \
+ JSSVGPathSegLinetoRel.h \
+ JSSVGPathSegLinetoVerticalAbs.h \
+ JSSVGPathSegLinetoVerticalRel.h \
+ JSSVGPathSegMovetoAbs.h \
+ JSSVGPathSegMovetoRel.h \
+ JSSVGNumber.h \
+ JSSVGNumberList.h \
+ JSSVGPaint.h \
+ JSSVGPathSegList.h \
+ JSSVGPatternElement.h \
+ JSSVGPoint.h \
+ JSSVGPointList.h \
+ JSSVGPolygonElement.h \
+ JSSVGPolylineElement.h \
+ JSSVGRadialGradientElement.h \
+ JSSVGRect.h \
+ JSSVGRectElement.h \
+ JSSVGRenderingIntent.h \
+ JSSVGSetElement.h \
+ JSSVGScriptElement.h \
+ JSSVGStyleElement.h \
+ JSSVGSwitchElement.h \
+ JSSVGStopElement.h \
+ JSSVGStringList.h \
+ JSSVGSymbolElement.h \
+ JSSVGTRefElement.h \
+ JSSVGTSpanElement.h \
+ JSSVGTextElement.h \
+ JSSVGTextContentElement.h \
+ JSSVGTextPathElement.h \
+ JSSVGTextPositioningElement.h \
+ JSSVGTitleElement.h \
+ JSSVGTransform.h \
+ JSSVGTransformList.h \
+ JSSVGUnitTypes.h \
+ JSSVGUseElement.h \
+ JSSVGViewElement.h \
+ JSSVGPreserveAspectRatio.h \
+ JSSVGElement.h \
+ JSSVGElementInstance.h \
+ JSSVGElementInstanceList.h \
+ JSSVGSVGElement.h \
+ JSSVGEllipseElement.h \
+ JSSVGFEBlendElement.h \
+ JSSVGFEColorMatrixElement.h \
+ JSSVGFEComponentTransferElement.h \
+ JSSVGFECompositeElement.h \
+ JSSVGFEDiffuseLightingElement.h \
+ JSSVGFEDisplacementMapElement.h \
+ JSSVGFEDistantLightElement.h \
+ JSSVGFEFloodElement.h \
+ JSSVGFEFuncAElement.h \
+ JSSVGFEFuncBElement.h \
+ JSSVGFEFuncGElement.h \
+ JSSVGFEFuncRElement.h \
+ JSSVGFEGaussianBlurElement.h \
+ JSSVGFEImageElement.h \
+ JSSVGFEMergeElement.h \
+ JSSVGFEMergeNodeElement.h \
+ JSSVGFEOffsetElement.h \
+ JSSVGFEPointLightElement.h \
+ JSSVGFESpecularLightingElement.h \
+ JSSVGFESpotLightElement.h \
+ JSSVGFETileElement.h \
+ JSSVGFETurbulenceElement.h \
+ JSSVGFilterElement.h \
+ JSSVGFontElement.h \
+ JSSVGFontFaceElement.h \
+ JSSVGFontFaceFormatElement.h \
+ JSSVGFontFaceNameElement.h \
+ JSSVGFontFaceSrcElement.h \
+ JSSVGFontFaceUriElement.h \
+ JSSVGForeignObjectElement.h \
+ JSSVGGElement.h \
+ JSSVGGlyphElement.h \
+ JSSVGGradientElement.h \
+ JSSVGImageElement.h \
+ JSSVGLength.h \
+ JSSVGLengthList.h \
+ JSSVGLineElement.h \
+ JSSVGLinearGradientElement.h \
+ JSSVGMaskElement.h \
+ JSSVGMarkerElement.h \
+ JSSVGMissingGlyphElement.h \
+ JSSVGTransform.h \
+ JSSVGZoomEvent.h \
+ JSScreen.h \
+ JSStyleSheet.h \
+ JSStyleSheetList.h \
+ JSText.h \
+ JSTextEvent.h \
+ JSTimeRanges.h \
+ JSTreeWalker.h \
+ JSUIEvent.h \
+ JSVoidCallback.h \
+ JSWheelEvent.h \
+ JSXMLHttpRequest.lut.h \
+ JSXMLHttpRequestException.h \
+ JSXMLSerializer.h \
+ JSXPathEvaluator.h \
+ JSXPathException.h \
+ JSXPathExpression.h \
+ JSXPathNSResolver.h \
+ JSXPathResult.h \
+ JSXSLTProcessor.lut.h \
+ SVGElementFactory.cpp \
+ SVGNames.cpp \
+ HTMLNames.cpp \
+ UserAgentStyleSheets.h \
+ XLinkNames.cpp \
+ XMLNames.cpp \
+ XPathGrammar.cpp \
+ kjs_css.lut.h \
+ kjs_events.lut.h \
+ kjs_navigator.lut.h \
+ kjs_window.lut.h \
+ tokenizer.cpp \
+ WebCore.exp \
+#
+
+all : \
+ CSSGrammar.cpp \
+ CSSPropertyNames.h \
+ CSSValueKeywords.h \
+ ColorData.c \
+ DocTypeStrings.cpp \
+ HTMLElementFactory.cpp \
+ HTMLEntityNames.c \
+ V8Attr.h \
+ V8BarInfo.h \
+ V8CanvasPixelArray.h \
+ V8ClientRect.h \
+ V8ClientRectList.h \
+ V8CDATASection.h \
+ V8CSSCharsetRule.h \
+ V8CSSFontFaceRule.h \
+ V8CSSImportRule.h \
+ V8CSSMediaRule.h \
+ V8CSSPageRule.h \
+ V8CSSPrimitiveValue.h \
+ V8CSSRule.h \
+ V8CSSRuleList.h \
+ V8CSSStyleRule.h \
+ V8CSSStyleSheet.h \
+ V8CSSValue.h \
+ V8CSSValueList.h \
+ V8CanvasGradient.h \
+ V8CanvasPattern.h \
+ V8CanvasRenderingContext2D.h \
+ V8CharacterData.h \
+ V8Comment.h \
+ V8Console.h \
+ V8Counter.h \
+ V8CSSStyleDeclaration.h \
+ V8CSSVariablesDeclaration.h \
+ V8CSSVariablesRule.h \
+ V8DOMCoreException.h \
+ V8DOMImplementation.h \
+ V8DOMParser.h \
+ V8DOMSelection.h \
+ V8DOMStringList.h \
+ V8DOMWindow.h \
+ V8Database.h \
+ V8Document.h \
+ V8DocumentFragment.h \
+ V8DocumentType.h \
+ V8Element.h \
+ V8Entity.h \
+ V8EntityReference.h \
+ V8Event.h \
+ V8EventException.h \
+ V8File.h \
+ V8FileList.h \
+ V8HTMLAnchorElement.h \
+ V8HTMLAppletElement.h \
+ V8HTMLAreaElement.h \
+ V8HTMLAudioElement.h \
+ V8HTMLBaseElement.h \
+ V8HTMLBaseFontElement.h \
+ V8HTMLBlockquoteElement.h \
+ V8HTMLBodyElement.h \
+ V8HTMLBRElement.h \
+ V8HTMLButtonElement.h \
+ V8HTMLCanvasElement.h \
+ V8HTMLCollection.h \
+ V8HTMLDListElement.h \
+ V8HTMLDirectoryElement.h \
+ V8HTMLDivElement.h \
+ V8HTMLDocument.h \
+ V8HTMLElement.h \
+ V8HTMLEmbedElement.h \
+ V8HTMLFieldSetElement.h \
+ V8HTMLFontElement.h \
+ V8HTMLFormElement.h \
+ V8HTMLFrameElement.h \
+ V8HTMLFrameSetElement.h \
+ V8HTMLHRElement.h \
+ V8HTMLHeadElement.h \
+ V8HTMLHeadingElement.h \
+ V8HTMLHtmlElement.h \
+ V8HTMLIFrameElement.h \
+ V8HTMLImageElement.h \
+ V8HTMLInputElement.h \
+ V8HTMLIsIndexElement.h \
+ V8HTMLLIElement.h \
+ V8HTMLLabelElement.h \
+ V8HTMLLegendElement.h \
+ V8HTMLLinkElement.h \
+ V8HTMLMapElement.h \
+ V8HTMLMarqueeElement.h \
+ V8HTMLMediaElement.h \
+ V8HTMLMenuElement.h \
+ V8HTMLMetaElement.h \
+ V8HTMLModElement.h \
+ V8HTMLOListElement.h \
+ V8HTMLOptGroupElement.h \
+ V8HTMLObjectElement.h \
+ V8HTMLOptionElement.h \
+ V8HTMLOptionsCollection.h \
+ V8HTMLParagraphElement.h \
+ V8HTMLParamElement.h \
+ V8HTMLPreElement.h \
+ V8HTMLQuoteElement.h \
+ V8HTMLScriptElement.h \
+ V8HTMLSelectElement.h \
+ V8HTMLSourceElement.h \
+ V8HTMLStyleElement.h \
+ V8HTMLTableCaptionElement.h \
+ V8HTMLTableCellElement.h \
+ V8HTMLTableColElement.h \
+ V8HTMLTableElement.h \
+ V8HTMLTableRowElement.h \
+ V8HTMLTableSectionElement.h \
+ V8HTMLTextAreaElement.h \
+ V8HTMLTitleElement.h \
+ V8HTMLUListElement.h \
+ V8HTMLVideoElement.h \
+ V8History.h \
+ V8ImageData.h \
+ V8KeyboardEvent.h \
+ V8MediaError.h \
+ V8MediaList.h \
+ V8MessageChannel.h \
+ V8MessageEvent.h \
+ V8MessagePort.h \
+ V8MouseEvent.h \
+ V8MutationEvent.h \
+ V8NamedNodeMap.h \
+ V8Node.h \
+ V8NodeFilter.h \
+ V8NodeIterator.h \
+ V8NodeList.h \
+ V8Notation.h \
+ V8OverflowEvent.h \
+ V8ProcessingInstruction.h \
+ V8ProgressEvent.h \
+ V8Range.h \
+ V8RangeException.h \
+ V8Rect.h \
+ V8SQLError.h \
+ V8SQLResultSet.h \
+ V8SQLResultSetRowList.h \
+ V8SQLTransaction.h \
+ V8SVGAElement.h \
+ V8SVGAltGlyphElement.h \
+ V8SVGAngle.h \
+ V8SVGAnimatedAngle.h \
+ V8SVGAnimateColorElement.h \
+ V8SVGAnimateElement.h \
+ V8SVGAnimateTransformElement.h \
+ V8SVGAnimatedBoolean.h \
+ V8SVGAnimatedEnumeration.h \
+ V8SVGAnimatedInteger.h \
+ V8SVGAnimatedLength.h \
+ V8SVGAnimatedLengthList.h \
+ V8SVGAnimatedNumber.h \
+ V8SVGAnimatedNumberList.h \
+ V8SVGAnimatedPreserveAspectRatio.h \
+ V8SVGAnimatedRect.h \
+ V8SVGAnimatedString.h \
+ V8SVGAnimatedTransformList.h \
+ V8SVGAnimationElement.h \
+ V8SVGColor.h \
+ V8SVGCircleElement.h \
+ V8SVGClipPathElement.h \
+ V8SVGComponentTransferFunctionElement.h \
+ V8SVGCursorElement.h \
+ V8SVGDefsElement.h \
+ V8SVGDefinitionSrcElement.h \
+ V8SVGDescElement.h \
+ V8SVGDocument.h \
+ V8SVGException.h \
+ V8SVGLength.h \
+ V8SVGMatrix.h \
+ V8SVGMetadataElement.h \
+ V8SVGPathElement.h \
+ V8SVGPathSeg.h \
+ V8SVGPathSegArcAbs.h \
+ V8SVGPathSegArcRel.h \
+ V8SVGPathSegClosePath.h \
+ V8SVGPathSegCurvetoCubicAbs.h \
+ V8SVGPathSegCurvetoCubicRel.h \
+ V8SVGPathSegCurvetoCubicSmoothAbs.h \
+ V8SVGPathSegCurvetoCubicSmoothRel.h \
+ V8SVGPathSegCurvetoQuadraticAbs.h \
+ V8SVGPathSegCurvetoQuadraticRel.h \
+ V8SVGPathSegCurvetoQuadraticSmoothAbs.h \
+ V8SVGPathSegCurvetoQuadraticSmoothRel.h \
+ V8SVGPathSegLinetoAbs.h \
+ V8SVGPathSegLinetoHorizontalAbs.h \
+ V8SVGPathSegLinetoHorizontalRel.h \
+ V8SVGPathSegLinetoRel.h \
+ V8SVGPathSegLinetoVerticalAbs.h \
+ V8SVGPathSegLinetoVerticalRel.h \
+ V8SVGPathSegMovetoAbs.h \
+ V8SVGPathSegMovetoRel.h \
+ V8SVGNumber.h \
+ V8SVGNumberList.h \
+ V8SVGPaint.h \
+ V8SVGPathSegList.h \
+ V8SVGPatternElement.h \
+ V8SVGPoint.h \
+ V8SVGPointList.h \
+ V8SVGPolygonElement.h \
+ V8SVGPolylineElement.h \
+ V8SVGRadialGradientElement.h \
+ V8SVGRect.h \
+ V8SVGRectElement.h \
+ V8SVGRenderingIntent.h \
+ V8SVGSetElement.h \
+ V8SVGScriptElement.h \
+ V8SVGStyleElement.h \
+ V8SVGSwitchElement.h \
+ V8SVGStopElement.h \
+ V8SVGStringList.h \
+ V8SVGSymbolElement.h \
+ V8SVGTRefElement.h \
+ V8SVGTSpanElement.h \
+ V8SVGTextElement.h \
+ V8SVGTextContentElement.h \
+ V8SVGTextPathElement.h \
+ V8SVGTextPositioningElement.h \
+ V8SVGTitleElement.h \
+ V8SVGTransform.h \
+ V8SVGTransformList.h \
+ V8SVGUnitTypes.h \
+ V8SVGUseElement.h \
+ V8SVGViewElement.h \
+ V8SVGPreserveAspectRatio.h \
+ V8SVGElement.h \
+ V8SVGElementInstance.h \
+ V8SVGElementInstanceList.h \
+ V8SVGSVGElement.h \
+ V8SVGEllipseElement.h \
+ V8SVGFEBlendElement.h \
+ V8SVGFEColorMatrixElement.h \
+ V8SVGFEComponentTransferElement.h \
+ V8SVGFECompositeElement.h \
+ V8SVGFEDiffuseLightingElement.h \
+ V8SVGFEDisplacementMapElement.h \
+ V8SVGFEDistantLightElement.h \
+ V8SVGFEFloodElement.h \
+ V8SVGFEFuncAElement.h \
+ V8SVGFEFuncBElement.h \
+ V8SVGFEFuncGElement.h \
+ V8SVGFEFuncRElement.h \
+ V8SVGFEGaussianBlurElement.h \
+ V8SVGFEImageElement.h \
+ V8SVGFEMergeElement.h \
+ V8SVGFEMergeNodeElement.h \
+ V8SVGFEOffsetElement.h \
+ V8SVGFEPointLightElement.h \
+ V8SVGFESpecularLightingElement.h \
+ V8SVGFESpotLightElement.h \
+ V8SVGFETileElement.h \
+ V8SVGFETurbulenceElement.h \
+ V8SVGFilterElement.h \
+ V8SVGFontElement.h \
+ V8SVGFontFaceElement.h \
+ V8SVGFontFaceFormatElement.h \
+ V8SVGFontFaceNameElement.h \
+ V8SVGFontFaceSrcElement.h \
+ V8SVGFontFaceUriElement.h \
+ V8SVGForeignObjectElement.h \
+ V8SVGGElement.h \
+ V8SVGGlyphElement.h \
+ V8SVGGradientElement.h \
+ V8SVGImageElement.h \
+ V8SVGLength.h \
+ V8SVGLengthList.h \
+ V8SVGLineElement.h \
+ V8SVGLinearGradientElement.h \
+ V8SVGMaskElement.h \
+ V8SVGMarkerElement.h \
+ V8SVGMissingGlyphElement.h \
+ V8SVGTransform.h \
+ V8SVGZoomEvent.h \
+ V8Screen.h \
+ V8StyleSheet.h \
+ V8StyleSheetList.h \
+ V8Text.h \
+ V8TextMetrics.h \
+ V8TextEvent.h \
+ V8TimeRanges.h \
+ V8TreeWalker.h \
+ V8UIEvent.h \
+ V8VoidCallback.h \
+ V8WebKitAnimationEvent.h \
+ V8WebKitCSSKeyframeRule.h \
+ V8WebKitCSSKeyframesRule.h \
+ V8WebKitCSSMatrix.h \
+ V8WebKitCSSTransformValue.h \
+ V8WebKitPoint.h \
+ V8WebKitTransitionEvent.h \
+ V8WheelEvent.h \
+ V8Worker.h \
+ V8WorkerContext.h \
+ V8WorkerLocation.h \
+ V8WorkerNavigator.h \
+ V8XMLHttpRequest.h \
+ V8XMLHttpRequestException.h \
+ V8XMLHttpRequestProgressEvent.h \
+ V8XMLHttpRequestUpload.h \
+ V8XMLSerializer.h \
+ V8XPathEvaluator.h \
+ V8XPathException.h \
+ V8XPathExpression.h \
+ V8XPathNSResolver.h \
+ V8XPathResult.h \
+ V8XSLTProcessor.h \
+ SVGElementFactory.cpp \
+ SVGNames.cpp \
+ HTMLNames.cpp \
+ UserAgentStyleSheets.h \
+ XLinkNames.cpp \
+ XMLNames.cpp \
+ XPathGrammar.cpp \
+ tokenizer.cpp \
+ V8Clipboard.h \
+ V8InspectorController.h \
+ V8Location.h \
+ V8Navigator.h \
+ V8MimeType.h \
+ V8MimeTypeArray.h \
+ V8Plugin.h \
+ V8PluginArray.h \
+ V8RGBColor.h \
+ V8SVGAnimatedPoints.h \
+ V8SVGURIReference.h \
+ V8UndetectableHTMLCollection.h \
+#
+
+# CSS property names and value keywords
+
+WEBCORE_CSS_PROPERTY_NAMES := $(WebCore)/css/CSSPropertyNames.in
+WEBCORE_CSS_VALUE_KEYWORDS := $(WebCore)/css/CSSValueKeywords.in
+
+ifeq ($(findstring ENABLE_SVG,$(FEATURE_DEFINES)), ENABLE_SVG)
+ WEBCORE_CSS_PROPERTY_NAMES := $(WEBCORE_CSS_PROPERTY_NAMES) $(WebCore)/css/SVGCSSPropertyNames.in
+ WEBCORE_CSS_VALUE_KEYWORDS := $(WEBCORE_CSS_VALUE_KEYWORDS) $(WebCore)/css/SVGCSSValueKeywords.in
+endif
+
+# Chromium does not support this.
+#ifeq ($(ENABLE_DASHBOARD_SUPPORT), 1)
+# WEBCORE_CSS_PROPERTY_NAMES := $(WEBCORE_CSS_PROPERTY_NAMES) $(WebCore)/css/DashboardSupportCSSPropertyNames.in
+#endif
+
+CSSPropertyNames.h : $(WEBCORE_CSS_PROPERTY_NAMES) css/makeprop.pl
+ if dos2unix $(WEBCORE_CSS_PROPERTY_NAMES) | sort | uniq -d | grep -E '^[^#]'; then echo 'Duplicate value!'; exit 1; fi
+ cat $(WEBCORE_CSS_PROPERTY_NAMES) > CSSPropertyNames.in
+ perl "$(WebCore)/css/makeprop.pl"
+
+CSSValueKeywords.h : $(WEBCORE_CSS_VALUE_KEYWORDS) css/makevalues.pl
+ # Lower case all the values, as CSS values are case-insensitive
+ perl -ne 'print lc' $(WEBCORE_CSS_VALUE_KEYWORDS) > CSSValueKeywords.in
+ if dos2unix CSSValueKeywords.in | sort | uniq -d | grep -E '^[^#]'; then echo 'Duplicate value!'; exit 1; fi
+ perl "$(WebCore)/css/makevalues.pl"
+
+# DOCTYPE strings
+
+DocTypeStrings.cpp : html/DocTypeStrings.gperf
+ gperf -CEot -L ANSI-C -k "*" -N findDoctypeEntry -F ,PubIDInfo::eAlmostStandards,PubIDInfo::eAlmostStandards $< > $@
+
+# HTML entity names
+
+HTMLEntityNames.c : html/HTMLEntityNames.gperf
+ gperf -a -L ANSI-C -C -G -c -o -t -k '*' -N findEntity -D -s 2 $< > $@
+
+# color names
+
+ColorData.c : platform/ColorData.gperf
+ gperf -CDEot -L ANSI-C -k '*' -N findColor -D -s 2 $< > $@
+
+# CSS tokenizer
+
+tokenizer.cpp : css/tokenizer.flex css/maketokenizer
+ flex -t $< | perl $(WebCore)/css/maketokenizer > $@
+
+# CSS grammar
+# NOTE: older versions of bison do not inject an inclusion guard, so we do it
+
+CSSGrammar.cpp : css/CSSGrammar.y
+ bison -d -p cssyy $< -o $@
+ touch CSSGrammar.cpp.h
+ touch CSSGrammar.hpp
+ echo '#ifndef CSSGrammar_h' > CSSGrammar.h
+ echo '#define CSSGrammar_h' >> CSSGrammar.h
+ cat CSSGrammar.cpp.h CSSGrammar.hpp >> CSSGrammar.h
+ echo '#endif' >> CSSGrammar.h
+ rm -f CSSGrammar.cpp.h CSSGrammar.hpp
+
+# XPath grammar
+# NOTE: older versions of bison do not inject an inclusion guard, so we do it
+
+XPathGrammar.cpp : xml/XPathGrammar.y $(PROJECT_FILE)
+ bison -d -p xpathyy $< -o $@
+ touch XPathGrammar.cpp.h
+ touch XPathGrammar.hpp
+ echo '#ifndef XPathGrammar_h' > XPathGrammar.h
+ echo '#define XPathGrammar_h' >> XPathGrammar.h
+ cat XPathGrammar.cpp.h XPathGrammar.hpp >> XPathGrammar.h
+ echo '#endif' >> XPathGrammar.h
+ rm -f XPathGrammar.cpp.h XPathGrammar.hpp
+
+# user agent style sheets
+
+USER_AGENT_STYLE_SHEETS = $(WebCore)/css/html4.css $(WebCore)/css/quirks.css $(WebCore)/css/view-source.css $(WebCore)/css/themeWin.css $(WebCore)/css/themeWinQuirks.css
+
+ifeq ($(findstring ENABLE_SVG,$(FEATURE_DEFINES)), ENABLE_SVG)
+ USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS) $(WebCore)/css/svg.css
+endif
+
+ifeq ($(findstring ENABLE_WML,$(FEATURE_DEFINES)), ENABLE_WML)
+ USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS) $(WebCore)/css/wml.css
+endif
+
+ifeq ($(findstring ENABLE_VIDEO,$(FEATURE_DEFINES)), ENABLE_VIDEO)
+ USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS) $(WebCore)/css/mediaControls.css
+endif
+
+UserAgentStyleSheets.h : css/make-css-file-arrays.pl $(USER_AGENT_STYLE_SHEETS)
+ perl $< $@ UserAgentStyleSheetsData.cpp $(USER_AGENT_STYLE_SHEETS)
+
+# character set name table
+
+CharsetData.cpp : platform/text/mac/make-charset-table.pl platform/text/mac/character-sets.txt $(ENCODINGS_FILE)
+ perl $^ $(ENCODINGS_PREFIX) > $@
+
+# lookup tables for old-style JavaScript bindings
+
+%.lut.h: %.cpp $(CREATE_HASH_TABLE)
+ $(CREATE_HASH_TABLE) $< > $@
+%Table.cpp: %.cpp $(CREATE_HASH_TABLE)
+ $(CREATE_HASH_TABLE) $< > $@
+
+# --------
+
+# HTML tag and attribute names
+
+ifeq ($(findstring ENABLE_VIDEO,$(FEATURE_DEFINES)), ENABLE_VIDEO)
+ HTML_FLAGS := $(HTML_FLAGS) ENABLE_VIDEO=1
+endif
+
+ifdef HTML_FLAGS
+
+HTMLElementFactory.cpp HTMLNames.cpp : dom/make_names.pl html/HTMLTagNames.in html/HTMLAttributeNames.in
+ perl -I $(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --factory --wrapperFactory --extraDefines "$(HTML_FLAGS)"
+
+else
+
+HTMLElementFactory.cpp HTMLNames.cpp : dom/make_names.pl html/HTMLTagNames.in html/HTMLAttributeNames.in
+ perl -I $(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --factory --wrapperFactory
+
+endif
+
+XMLNames.cpp : dom/make_names.pl xml/xmlattrs.in
+ perl -I $(WebCore)/bindings/scripts $< --attrs $(WebCore)/xml/xmlattrs.in
+
+# --------
+
+ifeq ($(findstring ENABLE_SVG,$(FEATURE_DEFINES)), ENABLE_SVG)
+
+WEBCORE_EXPORT_DEPENDENCIES := $(WEBCORE_EXPORT_DEPENDENCIES) WebCore.SVG.exp
+
+ifeq ($(findstring ENABLE_SVG_USE,$(FEATURE_DEFINES)), ENABLE_SVG_USE)
+ SVG_FLAGS := $(SVG_FLAGS) ENABLE_SVG_USE=1
+endif
+
+ifeq ($(findstring ENABLE_SVG_FONTS,$(FEATURE_DEFINES)), ENABLE_SVG_FONTS)
+ SVG_FLAGS := $(SVG_FLAGS) ENABLE_SVG_FONTS=1
+endif
+
+ifeq ($(findstring ENABLE_SVG_FILTERS,$(FEATURE_DEFINES)), ENABLE_SVG_FILTERS)
+ SVG_FLAGS := $(SVG_FLAGS) ENABLE_SVG_FILTERS=1
+ WEBCORE_EXPORT_DEPENDENCIES := $(WEBCORE_EXPORT_DEPENDENCIES) WebCore.SVG.Filters.exp
+endif
+
+ifeq ($(findstring ENABLE_SVG_AS_IMAGE,$(FEATURE_DEFINES)), ENABLE_SVG_AS_IMAGE)
+ SVG_FLAGS := $(SVG_FLAGS) ENABLE_SVG_AS_IMAGE=1
+endif
+
+ifeq ($(findstring ENABLE_SVG_ANIMATION,$(FEATURE_DEFINES)), ENABLE_SVG_ANIMATION)
+ SVG_FLAGS := $(SVG_FLAGS) ENABLE_SVG_ANIMATION=1
+ WEBCORE_EXPORT_DEPENDENCIES := $(WEBCORE_EXPORT_DEPENDENCIES) WebCore.SVG.Animation.exp
+endif
+
+ifeq ($(findstring ENABLE_SVG_FOREIGN_OBJECT,$(FEATURE_DEFINES)), ENABLE_SVG_FOREIGN_OBJECT)
+ SVG_FLAGS := $(SVG_FLAGS) ENABLE_SVG_FOREIGN_OBJECT=1
+ WEBCORE_EXPORT_DEPENDENCIES := $(WEBCORE_EXPORT_DEPENDENCIES) WebCore.SVG.ForeignObject.exp
+endif
+
+# SVG tag and attribute names (need to pass an extra flag if svg experimental features are enabled)
+
+ifdef SVG_FLAGS
+
+SVGElementFactory.cpp SVGNames.cpp : dom/make_names.pl svg/svgtags.in svg/svgattrs.in
+ perl -I $(WebCore)/bindings/scripts $< --tags $(WebCore)/svg/svgtags.in --attrs $(WebCore)/svg/svgattrs.in --extraDefines "$(SVG_FLAGS)" --factory --wrapperFactory
+else
+
+SVGElementFactory.cpp SVGNames.cpp : dom/make_names.pl svg/svgtags.in svg/svgattrs.in
+ perl -I $(WebCore)/bindings/scripts $< --tags $(WebCore)/svg/svgtags.in --attrs $(WebCore)/svg/svgattrs.in --factory --wrapperFactory
+
+endif
+
+JSSVGElementWrapperFactory.cpp : SVGNames.cpp
+
+XLinkNames.cpp : dom/make_names.pl svg/xlinkattrs.in
+ perl -I $(WebCore)/bindings/scripts $< --attrs $(WebCore)/svg/xlinkattrs.in
+
+else
+
+SVGElementFactory.cpp :
+ echo > $@
+
+SVGNames.cpp :
+ echo > $@
+
+XLinkNames.cpp :
+ echo > $@
+
+# This file is autogenerated by make_names.pl when SVG is enabled.
+
+JSSVGElementWrapperFactory.cpp :
+ echo > $@
+
+endif
+
+# new-style Objective-C bindings
+
+OBJC_BINDINGS_SCRIPTS = \
+ bindings/scripts/CodeGenerator.pm \
+ bindings/scripts/CodeGeneratorObjC.pm \
+ bindings/scripts/IDLParser.pm \
+ bindings/scripts/IDLStructure.pm \
+ bindings/scripts/generate-bindings.pl \
+#
+
+DOM%.h : %.idl $(OBJC_BINDINGS_SCRIPTS) $(PUBLICDOMINTERFACES)
+ perl -I $(WebCore)/bindings/scripts $(WebCore)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_OBJECTIVE_C" --generator ObjC --include dom --include html --include css --include page --include xml --include svg --include bindings/js --include plugins --outputdir . $<
+
+# new-style JavaScript bindings
+
+JS_BINDINGS_SCRIPTS = \
+ bindings/scripts/CodeGenerator.pm \
+ bindings/scripts/CodeGeneratorJS.pm \
+ bindings/scripts/IDLParser.pm \
+ bindings/scripts/IDLStructure.pm \
+ bindings/scripts/generate-bindings.pl \
+#
+
+JS%.h : %.idl $(JS_BINDINGS_SCRIPTS)
+ perl -I $(WebCore)/bindings/scripts $(WebCore)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --include css --include page --include xml --include svg --include bindings/js --include plugins --outputdir . $<
+
+# new-style V8 bindings
+
+V8_SCRIPTS = \
+ $(PORTROOT)/bindings/scripts/CodeGenerator.pm \
+ $(PORTROOT)/bindings/scripts/CodeGeneratorV8.pm \
+ $(PORTROOT)/bindings/scripts/IDLParser.pm \
+ $(WebCore)/bindings/scripts/IDLStructure.pm \
+ $(PORTROOT)/bindings/scripts/generate-bindings.pl \
+#
+
+# Sometimes script silently fails (Cygwin problem?),
+# use a bounded loop to retry if so, but not do so forever.
+V8%.h : %.idl $(V8_SCRIPTS)
+ rm -f $@; \
+ for i in 1 2 3 4 5 6 7 8 9 10; do \
+ if test -e $@; then break; fi; \
+ perl -w -I $(PORTROOT)/bindings/scripts -I $(WebCore)/bindings/scripts $(PORTROOT)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT V8_BINDING" --generator V8 --include svg --include dom --include html --include css --include page --include xml --include plugins --outputdir . $< ; \
+ done
diff --git a/V8Binding/V8Binding.derived.mk b/V8Binding/V8Binding.derived.mk
new file mode 100644
index 0000000..20c16d5
--- /dev/null
+++ b/V8Binding/V8Binding.derived.mk
@@ -0,0 +1,431 @@
+##
+##
+## Copyright 2007, The Android Open Source Project
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+
+LOCAL_CFLAGS += -DWTF_USE_V8=1
+
+v8binding_dir := $(LOCAL_PATH)
+
+BINDING_C_INCLUDES := \
+ $(BASE_PATH)/v8/include \
+ $(WEBCORE_PATH)/bindings/v8 \
+ $(WEBCORE_PATH)/bindings/v8/custom \
+ $(WEBCORE_PATH)/bridge/jni \
+ $(LOCAL_PATH)/v8 \
+ $(LOCAL_PATH)/npapi \
+ $(JAVASCRIPTCORE_PATH)/wtf \
+ $(JAVASCRIPTCORE_PATH)
+
+WEBCORE_SRC_FILES := \
+ bindings/v8/ScheduledAction.cpp \
+ bindings/v8/ScriptCallFrame.cpp \
+ bindings/v8/ScriptCallStack.cpp \
+ bindings/v8/ScriptInstance.cpp \
+ bindings/v8/ScriptValue.cpp \
+ bindings/v8/V8AbstractEventListener.cpp \
+ bindings/v8/V8DOMMap.cpp \
+ bindings/v8/V8LazyEventListener.cpp \
+ bindings/v8/V8NodeFilterCondition.cpp \
+ bindings/v8/V8ObjectEventListener.cpp \
+ bindings/v8/V8WorkerContextEventListener.cpp \
+ bindings/v8/V8XMLHttpRequestUtilities.cpp \
+ bindings/v8/WorkerContextExecutionProxy.cpp \
+ bindings/v8/WorkerScriptController.cpp \
+ \
+ bindings/v8/custom/V8AttrCustom.cpp \
+ bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp \
+ bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp \
+ bindings/v8/custom/V8ClipboardCustom.cpp \
+ bindings/v8/custom/V8CustomBinding.cpp \
+ bindings/v8/custom/V8CustomEventListener.cpp \
+ bindings/v8/custom/V8CustomVoidCallback.cpp \
+ bindings/v8/custom/V8DOMParserConstructor.cpp \
+ bindings/v8/custom/V8DOMStringListCustom.cpp \
+ bindings/v8/custom/V8DOMWindowCustom.cpp \
+ bindings/v8/custom/V8DocumentCustom.cpp \
+ bindings/v8/custom/V8ElementCustom.cpp \
+ bindings/v8/custom/V8EventCustom.cpp \
+ bindings/v8/custom/V8HTMLCanvasElementCustom.cpp \
+ bindings/v8/custom/V8HTMLCollectionCustom.cpp \
+ bindings/v8/custom/V8HTMLDocumentCustom.cpp \
+ bindings/v8/custom/V8HTMLFormElementCustom.cpp \
+ bindings/v8/custom/V8HTMLFrameElementCustom.cpp \
+ bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp \
+ bindings/v8/custom/V8HTMLIFrameElementCustom.cpp \
+ bindings/v8/custom/V8HTMLInputElementCustom.cpp \
+ bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp \
+ bindings/v8/custom/V8HTMLPlugInElementCustom.cpp \
+ bindings/v8/custom/V8HTMLSelectElementCustom.cpp \
+ bindings/v8/custom/V8LocationCustom.cpp \
+ bindings/v8/custom/V8MessageChannelConstructor.cpp \
+ bindings/v8/custom/V8NamedNodeMapCustom.cpp \
+ bindings/v8/custom/V8NamedNodesCollection.cpp \
+ bindings/v8/custom/V8NavigatorCustom.cpp \
+ bindings/v8/custom/V8NodeCustom.cpp \
+ bindings/v8/custom/V8NodeFilterCustom.cpp \
+ bindings/v8/custom/V8NodeIteratorCustom.cpp \
+ bindings/v8/custom/V8NodeListCustom.cpp \
+
+ifeq ($(ENABLE_STORAGE), true)
+WEBCORE_SRC_FILES := $(WEBCORE_SRC_FILES) \
+ bindings/v8/custom/V8DatabaseCustom.cpp \
+ bindings/v8/custom/V8SQLTransactionCustom.cpp
+ bindings/v8/custom/V8CustomSQLStatementCallback.cpp \
+ bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp \
+ bindings/v8/custom/V8CustomSQLTransactionCallback.cpp \
+ bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp \
+ bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
+endif
+
+ifeq ($(ENABLE_SVG), true)
+WEBCORE_SRC_FILES := $(WEBCORE_SRC_FILES) \
+ bindings/v8/custom/V8SVGElementInstanceCustom.cpp \
+ bindings/v8/custom/V8SVGLengthCustom.cpp \
+ bindings/v8/custom/V8SVGMatrixCustom.cpp
+endif
+
+WEBCORE_SRC_FILES := $(WEBCORE_SRC_FILES) \
+ bindings/v8/custom/V8StyleSheetListCustom.cpp \
+ bindings/v8/custom/V8TreeWalkerCustom.cpp \
+ bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp \
+ bindings/v8/custom/V8XMLHttpRequestConstructor.cpp \
+ bindings/v8/custom/V8XMLHttpRequestCustom.cpp \
+ bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp \
+ bindings/v8/custom/V8XMLSerializerConstructor.cpp \
+ \
+ bridge/jni/jni_utility.cpp
+
+LOCAL_SRC_FILES := \
+ v8/V8InitializeThreading.cpp \
+ v8/JSDOMBinding.cpp \
+ v8/JSXPathNSResolver.cpp \
+ v8/NPV8Object.cpp \
+ v8/RGBColor.cpp \
+ v8/ScriptController.cpp \
+ v8/V8CanvasPixelArrayCustom.cpp \
+ v8/V8MessagePortCustom.cpp \
+ v8/V8NPObject.cpp \
+ v8/V8NPUtils.cpp \
+ v8/V8WorkerContextCustom.cpp \
+ v8/V8WorkerCustom.cpp \
+ v8/npruntime.cpp \
+ v8/v8_binding.cpp \
+ v8/v8_custom.cpp \
+ v8/v8_helpers.cpp \
+ v8/v8_index.cpp \
+ v8/v8_proxy.cpp
+
+LOCAL_SHARED_LIBRARIES += libv8
+
+js_binding_scripts := \
+ $(LOCAL_PATH)/scripts/CodeGenerator.pm \
+ $(LOCAL_PATH)/scripts/CodeGeneratorV8.pm \
+ $(LOCAL_PATH)/scripts/IDLParser.pm \
+ $(WEBCORE_PATH)/bindings/scripts/IDLStructure.pm \
+ $(LOCAL_PATH)/scripts/generate-bindings.pl
+
+FEATURE_DEFINES := ANDROID_ORIENTATION_SUPPORT ENABLE_TOUCH_EVENTS=1 V8_BINDING
+
+GEN := \
+ $(intermediates)/css/V8CSSCharsetRule.h \
+ $(intermediates)/css/V8CSSFontFaceRule.h \
+ $(intermediates)/css/V8CSSImportRule.h \
+ $(intermediates)/css/V8CSSMediaRule.h \
+ $(intermediates)/css/V8CSSPageRule.h \
+ $(intermediates)/css/V8CSSPrimitiveValue.h \
+ $(intermediates)/css/V8CSSRule.h \
+ $(intermediates)/css/V8CSSRuleList.h \
+ $(intermediates)/css/V8CSSStyleDeclaration.h \
+ $(intermediates)/css/V8CSSStyleRule.h \
+ $(intermediates)/css/V8CSSStyleSheet.h \
+ $(intermediates)/css/V8CSSUnknownRule.h \
+ $(intermediates)/css/V8CSSValue.h \
+ $(intermediates)/css/V8CSSValueList.h \
+ $(intermediates)/css/V8CSSVariablesDeclaration.h \
+ $(intermediates)/css/V8CSSVariablesRule.h \
+ $(intermediates)/css/V8Counter.h \
+ $(intermediates)/css/V8MediaList.h \
+ $(intermediates)/css/V8Rect.h \
+ $(intermediates)/css/V8RGBColor.h \
+ $(intermediates)/css/V8StyleSheet.h \
+ $(intermediates)/css/V8StyleSheetList.h \
+ $(intermediates)/css/V8WebKitCSSKeyframeRule.h \
+ $(intermediates)/css/V8WebKitCSSKeyframesRule.h \
+ $(intermediates)/css/V8WebKitCSSMatrix.h \
+ $(intermediates)/css/V8WebKitCSSTransformValue.h
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include css --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/css/V8%.h : $(WEBCORE_PATH)/css/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/css/%.cpp : $(intermediates)/css/%.h
+
+GEN := \
+ $(intermediates)/dom/V8Attr.h \
+ $(intermediates)/dom/V8CDATASection.h \
+ $(intermediates)/dom/V8CharacterData.h \
+ $(intermediates)/dom/V8ClientRect.h \
+ $(intermediates)/dom/V8ClientRectList.h \
+ $(intermediates)/dom/V8Clipboard.h \
+ $(intermediates)/dom/V8Comment.h \
+ $(intermediates)/dom/V8DOMCoreException.h \
+ $(intermediates)/dom/V8DOMImplementation.h \
+ $(intermediates)/dom/V8DOMStringList.h \
+ $(intermediates)/dom/V8Document.h \
+ $(intermediates)/dom/V8DocumentFragment.h \
+ $(intermediates)/dom/V8DocumentType.h \
+ $(intermediates)/dom/V8Element.h \
+ $(intermediates)/dom/V8Entity.h \
+ $(intermediates)/dom/V8EntityReference.h \
+ $(intermediates)/dom/V8Event.h \
+ $(intermediates)/dom/V8EventException.h \
+ $(intermediates)/dom/V8KeyboardEvent.h \
+ $(intermediates)/dom/V8MessageChannel.h \
+ $(intermediates)/dom/V8MessageEvent.h \
+ $(intermediates)/dom/V8MessagePort.h \
+ $(intermediates)/dom/V8MouseEvent.h \
+ $(intermediates)/dom/V8MutationEvent.h \
+ $(intermediates)/dom/V8NamedNodeMap.h \
+ $(intermediates)/dom/V8Node.h \
+ $(intermediates)/dom/V8NodeFilter.h \
+ $(intermediates)/dom/V8NodeIterator.h \
+ $(intermediates)/dom/V8NodeList.h \
+ $(intermediates)/dom/V8Notation.h \
+ $(intermediates)/dom/V8OverflowEvent.h \
+ $(intermediates)/dom/V8ProcessingInstruction.h \
+ $(intermediates)/dom/V8ProgressEvent.h \
+ $(intermediates)/dom/V8Range.h \
+ $(intermediates)/dom/V8RangeException.h \
+ $(intermediates)/dom/V8Text.h \
+ $(intermediates)/dom/V8TextEvent.h \
+ $(intermediates)/dom/V8Touch.h \
+ $(intermediates)/dom/V8TouchEvent.h \
+ $(intermediates)/dom/V8TouchList.h \
+ $(intermediates)/dom/V8TreeWalker.h \
+ $(intermediates)/dom/V8UIEvent.h \
+ $(intermediates)/dom/V8WebKitAnimationEvent.h \
+ $(intermediates)/dom/V8WebKitTransitionEvent.h \
+ $(intermediates)/dom/V8WheelEvent.h
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/dom/V8%.h : $(WEBCORE_PATH)/dom/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/dom/%.cpp : $(intermediates)/dom/%.h
+
+
+GEN := \
+ $(intermediates)/html/V8CanvasGradient.h \
+ $(intermediates)/html/V8CanvasPattern.h \
+ $(intermediates)/html/V8CanvasPixelArray.h \
+ $(intermediates)/html/V8CanvasRenderingContext2D.h \
+ $(intermediates)/html/V8File.h \
+ $(intermediates)/html/V8FileList.h \
+ $(intermediates)/html/V8HTMLAnchorElement.h \
+ $(intermediates)/html/V8HTMLAppletElement.h \
+ $(intermediates)/html/V8HTMLAreaElement.h \
+ $(intermediates)/html/V8HTMLBRElement.h \
+ $(intermediates)/html/V8HTMLBaseElement.h \
+ $(intermediates)/html/V8HTMLBaseFontElement.h \
+ $(intermediates)/html/V8HTMLBlockquoteElement.h \
+ $(intermediates)/html/V8HTMLBodyElement.h \
+ $(intermediates)/html/V8HTMLButtonElement.h \
+ $(intermediates)/html/V8HTMLCanvasElement.h \
+ $(intermediates)/html/V8HTMLCollection.h \
+ $(intermediates)/html/V8HTMLDListElement.h \
+ $(intermediates)/html/V8HTMLDirectoryElement.h \
+ $(intermediates)/html/V8HTMLDivElement.h \
+ $(intermediates)/html/V8HTMLDocument.h \
+ $(intermediates)/html/V8HTMLElement.h \
+ $(intermediates)/html/V8HTMLEmbedElement.h \
+ $(intermediates)/html/V8HTMLFieldSetElement.h \
+ $(intermediates)/html/V8HTMLFontElement.h \
+ $(intermediates)/html/V8HTMLFormElement.h \
+ $(intermediates)/html/V8HTMLFrameElement.h \
+ $(intermediates)/html/V8HTMLFrameSetElement.h \
+ $(intermediates)/html/V8HTMLHRElement.h \
+ $(intermediates)/html/V8HTMLHeadElement.h \
+ $(intermediates)/html/V8HTMLHeadingElement.h \
+ $(intermediates)/html/V8HTMLHtmlElement.h \
+ $(intermediates)/html/V8HTMLIFrameElement.h \
+ $(intermediates)/html/V8HTMLImageElement.h \
+ $(intermediates)/html/V8HTMLInputElement.h \
+ $(intermediates)/html/V8HTMLIsIndexElement.h \
+ $(intermediates)/html/V8HTMLLIElement.h \
+ $(intermediates)/html/V8HTMLLabelElement.h \
+ $(intermediates)/html/V8HTMLLegendElement.h \
+ $(intermediates)/html/V8HTMLLinkElement.h \
+ $(intermediates)/html/V8HTMLMapElement.h \
+ $(intermediates)/html/V8HTMLMarqueeElement.h \
+ $(intermediates)/html/V8HTMLMenuElement.h \
+ $(intermediates)/html/V8HTMLMetaElement.h \
+ $(intermediates)/html/V8HTMLModElement.h \
+ $(intermediates)/html/V8HTMLOListElement.h \
+ $(intermediates)/html/V8HTMLObjectElement.h \
+ $(intermediates)/html/V8HTMLOptGroupElement.h \
+ $(intermediates)/html/V8HTMLOptionElement.h \
+ $(intermediates)/html/V8HTMLOptionsCollection.h \
+ $(intermediates)/html/V8HTMLParagraphElement.h \
+ $(intermediates)/html/V8HTMLParamElement.h \
+ $(intermediates)/html/V8HTMLPreElement.h \
+ $(intermediates)/html/V8HTMLQuoteElement.h \
+ $(intermediates)/html/V8HTMLScriptElement.h \
+ $(intermediates)/html/V8HTMLSelectElement.h \
+ $(intermediates)/html/V8HTMLSourceElement.h \
+ $(intermediates)/html/V8HTMLStyleElement.h \
+ $(intermediates)/html/V8HTMLTableCaptionElement.h \
+ $(intermediates)/html/V8HTMLTableCellElement.h \
+ $(intermediates)/html/V8HTMLTableColElement.h \
+ $(intermediates)/html/V8HTMLTableElement.h \
+ $(intermediates)/html/V8HTMLTableRowElement.h \
+ $(intermediates)/html/V8HTMLTableSectionElement.h \
+ $(intermediates)/html/V8HTMLTextAreaElement.h \
+ $(intermediates)/html/V8HTMLTitleElement.h \
+ $(intermediates)/html/V8HTMLUListElement.h \
+ $(intermediates)/html/V8HTMLVideoElement.h \
+ $(intermediates)/html/V8ImageData.h \
+ $(intermediates)/html/V8MediaError.h \
+ $(intermediates)/html/V8TextMetrics.h \
+ $(intermediates)/html/V8TimeRanges.h \
+ $(intermediates)/html/V8VoidCallback.h
+
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/html/V8%.h : $(WEBCORE_PATH)/html/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/html/%.cpp : $(intermediates)/html/%.h
+
+
+GEN := \
+ $(intermediates)/page/V8BarInfo.h \
+ $(intermediates)/page/V8Console.h \
+ $(intermediates)/page/V8Coordinates.h \
+ $(intermediates)/page/V8DOMSelection.h \
+ $(intermediates)/page/V8DOMWindow.h \
+ $(intermediates)/page/V8Geolocation.h \
+ $(intermediates)/page/V8Geoposition.h \
+ $(intermediates)/page/V8History.h \
+ $(intermediates)/page/V8Location.h \
+ $(intermediates)/page/V8Navigator.h \
+ $(intermediates)/page/V8PositionError.h \
+ $(intermediates)/page/V8PositionErrorCallback.h \
+ $(intermediates)/page/V8Screen.h \
+ $(intermediates)/page/V8WebKitPoint.h
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/page/V8%.h : $(WEBCORE_PATH)/page/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/page/%.cpp : $(intermediates)/page/%.h
+
+GEN := \
+ $(intermediates)/plugins/V8MimeType.h \
+ $(intermediates)/plugins/V8MimeTypeArray.h \
+ $(intermediates)/plugins/V8Plugin.h \
+ $(intermediates)/plugins/V8PluginArray.h
+
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/plugins/V8%.h : $(WEBCORE_PATH)/plugins/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/plugins/%.cpp : $(intermediates)/plugins/%.h
+
+ifeq ($(ENABLE_STORAGE),true)
+# Storage support
+GEN := \
+ $(intermediates)/storage/V8Database.h \
+ $(intermediates)/storage/V8SQLError.h \
+ $(intermediates)/storage/V8SQLResultSet.h \
+ $(intermediates)/storage/V8SQLResultSetRowList.h \
+ $(intermediates)/storage/V8SQLTransaction.h \
+ $(intermediates)/storage/V8Storage.h \
+ $(intermediates)/storage/V8StorageEvent.h
+
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/storage/V8%.h : $(WEBCORE_PATH)/storage/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/storage/%.cpp : $(intermediates)/storage/%.h
+endif
+
+#new section for xml/DOMParser.idl
+GEN := \
+ $(intermediates)/xml/V8DOMParser.h \
+ $(intermediates)/xml/V8XMLHttpRequest.h \
+ $(intermediates)/xml/V8XMLHttpRequestException.h \
+ $(intermediates)/xml/V8XMLHttpRequestProgressEvent.h \
+ $(intermediates)/xml/V8XMLHttpRequestUpload.h \
+ $(intermediates)/xml/V8XMLSerializer.h
+
+
+# $(intermediates)/xml/V8XPathEvaluator.h \
+ $(intermediates)/xml/V8XPathException.h \
+ $(intermediates)/xml/V8XPathExpression.h \
+ $(intermediates)/xml/V8XPathNSResolver.h \
+ $(intermediates)/xml/V8XPathResult.h \
+ $(intermediates)/xml/V8XSLTProcessor.h
+
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/xml/V8%.h : $(WEBCORE_PATH)/xml/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/xml/%.cpp : $(intermediates)/xml/%.h
+#end
+
+#new section for UndetectableHTMLCollection
+GEN := \
+ $(intermediates)/html/V8UndetectableHTMLCollection.h
+
+$(GEN): PRIVATE_CUSTOM_TOOL = SOURCE_ROOT=$(WEBCORE_PATH) perl -I$(v8binding_dir)/scripts -I$(WEBCORE_PATH)/bindings/scripts $(v8binding_dir)/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator V8 --include dom --include html --outputdir $(dir $@) $<
+$(GEN): $(intermediates)/html/V8%.h : $(v8binding_dir)/v8/%.idl $(js_binding_scripts)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN) $(GEN:%.h=%.cpp)
+
+# We also need the .cpp files, which are generated as side effects of the
+# above rules. Specifying this explicitly makes -j2 work.
+$(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/html/%.cpp : $(intermediates)/html/%.h
+#end
+
+# HTML tag and attribute names
+
+GEN:= $(intermediates)/HTMLNames.cpp $(intermediates)/HTMLElementFactory.cpp
+$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
+$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(WEBCORE_PATH)/bindings/scripts $< --tags $(html_tags) --attrs $(html_attrs) --factory --wrapperFactory --output $(dir $@)
+$(GEN): html_tags := $(WEBCORE_PATH)/html/HTMLTagNames.in
+$(GEN): html_attrs := $(WEBCORE_PATH)/html/HTMLAttributeNames.in
+$(GEN): $(WEBCORE_PATH)/dom/make_names.pl $(html_tags) $(html_attrs)
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
diff --git a/V8Binding/jni/jni_class.cpp b/V8Binding/jni/jni_class.cpp
new file mode 100644
index 0000000..4e3b5f9
--- /dev/null
+++ b/V8Binding/jni/jni_class.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "jni_class.h"
+
+#if ENABLE(MAC_JAVA_BRIDGE)
+
+#include "JSDOMWindow.h"
+#include <runtime/Identifier.h>
+#include <runtime/JSLock.h>
+#include "jni_utility.h"
+#include "jni_runtime.h"
+
+using namespace JSC::Bindings;
+
+JavaClass::JavaClass(jobject anInstance)
+{
+ jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
+
+ if (!aClass) {
+ fprintf(stderr, "%s: unable to call getClass on instance %p\n", __PRETTY_FUNCTION__, anInstance);
+ return;
+ }
+
+ jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;");
+ const char *classNameC = getCharactersFromJString(className);
+ _name = strdup(classNameC);
+ releaseCharactersForJString(className, classNameC);
+
+ int i;
+ JNIEnv *env = getJNIEnv();
+
+ // Get the fields
+ jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;");
+ int numFields = env->GetArrayLength(fields);
+ for (i = 0; i < numFields; i++) {
+ jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
+ JavaField *aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
+ {
+ JSLock lock(false);
+ _fields.set(aField->name(), aField);
+ }
+ env->DeleteLocalRef(aJField);
+ }
+
+ // Get the methods
+ jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;");
+ int numMethods = env->GetArrayLength(methods);
+ for (i = 0; i < numMethods; i++) {
+ jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
+ JavaMethod *aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
+ MethodList* methodList;
+ {
+ JSLock lock(false);
+
+ methodList = _methods.get(aMethod->name());
+ if (!methodList) {
+ methodList = new MethodList();
+ _methods.set(aMethod->name(), methodList);
+ }
+ }
+ methodList->append(aMethod);
+ env->DeleteLocalRef(aJMethod);
+ }
+#ifdef ANDROID_FIX
+ env->DeleteLocalRef(fields);
+ env->DeleteLocalRef(methods);
+ env->DeleteLocalRef(aClass);
+#endif
+}
+
+JavaClass::~JavaClass() {
+ free((void *)_name);
+
+ JSLock lock(false);
+
+ deleteAllValues(_fields);
+ _fields.clear();
+
+ MethodListMap::const_iterator end = _methods.end();
+ for (MethodListMap::const_iterator it = _methods.begin(); it != end; ++it) {
+ const MethodList* methodList = it->second;
+ deleteAllValues(*methodList);
+ delete methodList;
+ }
+ _methods.clear();
+}
+
+MethodList JavaClass::methodsNamed(const Identifier& identifier, Instance*) const
+{
+ MethodList *methodList = _methods.get(identifier.ustring().rep());
+
+ if (methodList)
+ return *methodList;
+ return MethodList();
+}
+
+Field *JavaClass::fieldNamed(const Identifier& identifier, Instance*) const
+{
+ return _fields.get(identifier.ustring().rep());
+}
+
+bool JavaClass::isNumberClass() const
+{
+ return ((strcmp(_name, "java.lang.Byte") == 0 ||
+ strcmp(_name, "java.lang.Short") == 0 ||
+ strcmp(_name, "java.lang.Integer") == 0 ||
+ strcmp(_name, "java.lang.Long") == 0 ||
+ strcmp(_name, "java.lang.Float") == 0 ||
+ strcmp(_name, "java.lang.Double") == 0) );
+}
+
+bool JavaClass::isBooleanClass() const
+{
+ return strcmp(_name, "java.lang.Boolean") == 0;
+}
+
+bool JavaClass::isStringClass() const
+{
+ return strcmp(_name, "java.lang.String") == 0;
+}
+
+#endif // ENABLE(MAC_JAVA_BRIDGE)
diff --git a/V8Binding/jni/jni_class.h b/V8Binding/jni/jni_class.h
new file mode 100644
index 0000000..2865be5
--- /dev/null
+++ b/V8Binding/jni/jni_class.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JNI_CLASS_H_
+#define JNI_CLASS_H_
+
+#include <jni_runtime.h>
+#include <wtf/HashMap.h>
+
+namespace JSC {
+
+namespace Bindings {
+
+typedef Vector<JavaMethod*> MethodList;
+class JavaClass
+public:
+ JavaClass (jobject anInstance);
+ ~JavaClass ();
+
+ MethodList methodsNamed(NPIdentifier name, Instance* instance) const;
+
+private:
+ const char *_name;
+ MethodListMap _methods;
+};
+
+} // namespace Bindings
+
+} // namespace JSC
+
+#endif // JNI_CLASS_H_
diff --git a/V8Binding/jni/jni_instance.cpp b/V8Binding/jni/jni_instance.cpp
new file mode 100644
index 0000000..887886e
--- /dev/null
+++ b/V8Binding/jni/jni_instance.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "jni_instance.h"
+#include "jni_runtime.h"
+#include "jni_utility.h"
+
+#include <assert.h>
+
+#ifdef NDEBUG
+#define JS_LOG(formatAndArgs...) ((void)0)
+#else
+#define JS_LOG(formatAndArgs...) { \
+ fprintf (stderr, "%s:%d -- %s: ", __FILE__, __LINE__, __FUNCTION__); \
+ fprintf(stderr, formatAndArgs); \
+}
+#endif
+
+using namespace JSC::Bindings;
+
+JavaInstance::JavaInstance (jobject instance)
+{
+ _instance = new JObjectWrapper (instance);
+}
+
+JavaInstance::~JavaInstance ()
+{
+}
+
+#define NUM_LOCAL_REFS 64
+
+bool JavaInstance::invokeMethod(NPIdentifier methodName, NPVariant* args, uint32_t count, NPVariant* resultValue)
+{
+ int i;
+ jvalue *jArgs;
+ Method *method = 0;
+ size_t numMethods = methodList.size();
+
+ // Try to find a good match for the overloaded method. The
+ // fundamental problem is that JavaScript doesn have the
+ // notion of method overloading and Java does. We could
+ // get a bit more sophisticated and attempt to does some
+ // type checking as we as checking the number of parameters.
+ Method *aMethod;
+ for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) {
+ aMethod = methodList[methodIndex];
+ if (aMethod->numParameters() == count) {
+ method = aMethod;
+ break;
+ }
+ }
+ if (method == 0) {
+ JS_LOG ("unable to find an appropiate method\n");
+ return jsUndefined();
+ }
+
+ const JavaMethod *jMethod = static_cast<const JavaMethod*>(method);
+
+ if (count > 0) {
+ jArgs = (jvalue *)malloc (count * sizeof(jvalue));
+ }
+ else
+ jArgs = 0;
+
+ for (i = 0; i < count; i++) {
+ JavaParameter* aParameter = jMethod->parameterAt(i);
+ jArgs[i] = convertNPVariantToJValue(args[i], aParameter->getJNIType(), aParameter->type());
+ }
+
+ jvalue result;
+
+ // The following code can be conditionally removed once we have a Tiger update that
+ // contains the new Java plugin. It is needed for builds prior to Tiger.
+ {
+ jobject obj = _instance->_instance;
+ switch (jMethod->JNIReturnType()){
+ case void_type:
+ callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case object_type:
+ result.l = callJNIMethodIDA<jobject>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case boolean_type:
+ result.z = callJNIMethodIDA<jboolean>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case byte_type:
+ result.b = callJNIMethodIDA<jbyte>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case char_type:
+ result.c = callJNIMethodIDA<jchar>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case short_type:
+ result.s = callJNIMethodIDA<jshort>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case int_type:
+ result.i = callJNIMethodIDA<jint>(obj, jMethod->methodID(obj), jArgs);
+ break;
+
+ case long_type:
+ result.j = callJNIMethodIDA<jlong>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case float_type:
+ result.f = callJNIMethodIDA<jfloat>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case double_type:
+ result.d = callJNIMethodIDA<jdouble>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case invalid_type:
+ default:
+ break;
+ }
+ }
+
+ switch (jMethod->JNIReturnType()){
+ case void_type: {
+ VOID_TO_NPVARIANT(*resultValue);
+ }
+ break;
+
+ case object_type: {
+ if (result.l != 0) {
+ OBJECT_TO_NPVARIANT(JavaObjectToNPObject(JavaInstance::create(result.l)), *resultValue);
+ }
+ else {
+ VOID_TO_NPVARIANT(*resultValue);
+ }
+ }
+ break;
+
+ case boolean_type: {
+ BOOLEAN_TO_NPVARIANT(result.z, *resultValue);
+ }
+ break;
+
+ case byte_type: {
+ INT32_TO_NPVARIANT(result.b, *resultValue);
+ }
+ break;
+
+ case char_type: {
+ INT32_TO_NPVARIANT(result.c, *resultValue);
+ }
+ break;
+
+ case short_type: {
+ INT32_TO_NPVARIANT(result.s, *resultValue);
+ }
+ break;
+
+ case int_type: {
+ INT32_TO_NPVARIANT(result.i, *resultValue);
+ }
+ break;
+
+ // TODO(fqian): check if cast to double is needed.
+ case long_type: {
+ DOUBLE_TO_NPVARIANT(result.j, *resultValue);
+ }
+ break;
+
+ case float_type: {
+ DOUBLE_TO_NPVARIANT(result.f, *resultValue);
+ }
+ break;
+
+ case double_type: {
+ DOUBLE_TO_NPVARIANT(result.d, *resultValue);
+ }
+ break;
+
+ case invalid_type:
+ default: {
+ VOID_TO_NPVARIANT(*resultValue);
+ }
+ break;
+ }
+
+ free (jArgs);
+
+ return resultValue;
+}
+
+JObjectWrapper::JObjectWrapper(jobject instance)
+: _refCount(0)
+{
+ assert (instance != 0);
+
+ // Cache the JNIEnv used to get the global ref for this java instanace.
+ // It'll be used to delete the reference.
+ _env = getJNIEnv();
+
+ _instance = _env->NewGlobalRef (instance);
+
+ JS_LOG ("new global ref %p for %p\n", _instance, instance);
+
+ if (_instance == NULL) {
+ fprintf (stderr, "%s: could not get GlobalRef for %p\n", __PRETTY_FUNCTION__, instance);
+ }
+}
+
+JObjectWrapper::~JObjectWrapper() {
+ JS_LOG ("deleting global ref %p\n", _instance);
+ _env->DeleteGlobalRef (_instance);
+}
diff --git a/V8Binding/jni/jni_instance.h b/V8Binding/jni/jni_instance.h
new file mode 100644
index 0000000..5fa4141
--- /dev/null
+++ b/V8Binding/jni/jni_instance.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _JNI_INSTANCE_H_
+#define _JNI_INSTANCE_H_
+
+#include <JavaVM/jni.h>
+
+namespace android {
+class WeakJavaInstance;
+}
+
+namespace JSC {
+
+namespace Bindings {
+
+class JObjectWrapper
+{
+friend class RefPtr<JObjectWrapper>;
+friend class JavaArray;
+friend class JavaInstance;
+friend class JavaMethod;
+friend class android::WeakJavaInstance;
+
+protected:
+ JObjectWrapper(jobject instance);
+ ~JObjectWrapper();
+
+ void ref() { _refCount++; }
+ void deref()
+ {
+ if (--_refCount == 0)
+ delete this;
+ }
+
+ jobject _instance;
+
+private:
+ JNIEnv *_env;
+ unsigned int _refCount;
+};
+
+class JavaInstance
+{
+public:
+ static PassRefPtr<JavaInstance> create(jobject instance)
+ {
+ return adoptRef(new JavaInstance(instance));
+ }
+
+ ~JavaInstance();
+
+ NPVariant invokeMethod(NPIdentifier methodName, NPVariant* args, uint32_t argsCount);
+
+ jobject javaInstance() const { return _instance->_instance; }
+
+private:
+ JavaInstance(jobject instance);
+
+ RefPtr<JObjectWrapper> _instance;
+};
+
+} // namespace Bindings
+
+} // namespace JSC
+
+#endif // _JNI_INSTANCE_H_
diff --git a/V8Binding/jni/jni_npobject.cpp b/V8Binding/jni/jni_npobject.cpp
new file mode 100644
index 0000000..daa26a8
--- /dev/null
+++ b/V8Binding/jni/jni_npobject.cpp
@@ -0,0 +1,46 @@
+
+#include "jni_npobject.h"
+
+namespace V8 { namespace Binding {
+
+static NPClass JavaNPClass = {
+ NP_CLASS_STRUCT_VERSION,
+ 0, // allocate,
+ 0, // free,
+ 0, // invalidate
+ JavaNPObject_HasMethod,
+ JavaNPObject_Invoke,
+ 0, // invokeDefault,
+ JavaNPObject_HasProperty,
+ JavaNPobject_GetProperty,
+ JavaNPObject_SetProperty,
+ 0, // removeProperty
+ 0, // enumerate
+ 0 // construct
+};
+
+NPObject* JavaInstanceToNPObject(PassRefPtr<JavaInstance> instance) {
+ JavaNPObject* object = new JavaNPObject(instance);
+ return static_cast<NPObject*>(object);
+}
+
+bool JavaNPObject_HasMethod(NPObject* obj, NPIdentifier name) {
+ // FIXME: for now, always pretend the object has the named method.
+ return true;
+}
+
+bool JavaNPObject_Invoke(NPobject* obj, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result) {
+
+}
+
+bool JavaNPObject_HasProperty(NPObject* obj, NPIdentifier name) {
+}
+
+bool JavaNPObject_GetProperty(NPObject* obj, NPIdentifier name, NPVariant* ressult) {
+}
+
+bool JavaNPObject_SetProperty(NPObject* obj, NPIdentifier name, const NPVariant* value) {
+
+}
+
+} } // namespace V8::Binding
diff --git a/V8Binding/jni/jni_npobject.h b/V8Binding/jni/jni_npobject.h
new file mode 100644
index 0000000..99fe368
--- /dev/null
+++ b/V8Binding/jni/jni_npobject.h
@@ -0,0 +1,27 @@
+// A wrapper of a JNI value as an NPObject
+
+
+#ifndef JNI_NPOBJECT_H_
+#define JNI_NPOBJECT_H_
+
+#include "npapi.h"
+#include <JavaVM/jni.h>
+
+namespace V8 { namespace V8Binding {
+
+struct JavaNPObject {
+ NPObject _object;
+ RefPtr<JavaInstance> _instance;
+};
+
+NPObject* JavaInstanceToNPObject(PassRefPtr<JavaInstance> instance);
+
+bool JavaNPObject_HasMethod(NPObject* obj, NPIdentifier name);
+bool JavaNPObject_Invoke(NPobject* obj, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result);
+bool JavaNPObject_HasProperty(NPObject* obj, NPIdentifier name);
+bool JavaNPObject_GetProperty(NPObject* obj, NPIdentifier name, NPVariant* ressult);
+bool JavaNPObject_SetProperty(NPObject* obj, NPIdentifier name, const NPVariant* value);
+
+} }
+
+#endif JNI_NPOBJECT_H_
diff --git a/V8Binding/jni/jni_runtime.cpp b/V8Binding/jni/jni_runtime.cpp
new file mode 100644
index 0000000..1ff640a
--- /dev/null
+++ b/V8Binding/jni/jni_runtime.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "jni_runtime.h"
+#include "jni_utility.h"
+
+#ifdef NDEBUG
+#define JS_LOG(formatAndArgs...) ((void)0)
+#else
+#define JS_LOG(formatAndArgs...) { \
+ fprintf (stderr, "%s:%d -- %s: ", __FILE__, __LINE__, __FUNCTION__); \
+ fprintf(stderr, formatAndArgs); \
+}
+#endif
+
+using namespace JSC::Bindings;
+
+JavaParameter::JavaParameter (JNIEnv *env, jstring type)
+{
+ _type = JavaString (env, type);
+ _JNIType = JNITypeFromClassName (_type.UTF8String());
+}
+
+
+JavaMethod::JavaMethod (JNIEnv *env, jobject aMethod)
+{
+ // Get return type
+ jobject returnType = callJNIMethod<jobject>(aMethod, "getReturnType", "()Ljava/lang/Class;");
+ jstring returnTypeName = (jstring)callJNIMethod<jobject>(returnType, "getName", "()Ljava/lang/String;");
+ _returnType =JavaString (env, returnTypeName);
+ _JNIReturnType = JNITypeFromClassName (_returnType.UTF8String());
+ env->DeleteLocalRef (returnType);
+ env->DeleteLocalRef (returnTypeName);
+
+ // Get method name
+ jstring methodName = (jstring)callJNIMethod<jobject>(aMethod, "getName", "()Ljava/lang/String;");
+ _name = JavaString (env, methodName);
+ env->DeleteLocalRef (methodName);
+
+ // Get parameters
+ jarray jparameters = (jarray)callJNIMethod<jobject>(aMethod, "getParameterTypes", "()[Ljava/lang/Class;");
+ _numParameters = env->GetArrayLength (jparameters);
+ _parameters = new JavaParameter[_numParameters];
+
+ int i;
+ for (i = 0; i < _numParameters; i++) {
+ jobject aParameter = env->GetObjectArrayElement ((jobjectArray)jparameters, i);
+ jstring parameterName = (jstring)callJNIMethod<jobject>(aParameter, "getName", "()Ljava/lang/String;");
+ _parameters[i] = JavaParameter(env, parameterName);
+ env->DeleteLocalRef (aParameter);
+ env->DeleteLocalRef (parameterName);
+ }
+ env->DeleteLocalRef (jparameters);
+
+ // Created lazily.
+ _signature = 0;
+ _methodID = 0;
+
+ jclass modifierClass = env->FindClass("java/lang/reflect/Modifier");
+ int modifiers = callJNIMethod<jint>(aMethod, "getModifiers", "()I");
+ _isStatic = (bool)callJNIStaticMethod<jboolean>(modifierClass, "isStatic", "(I)Z", modifiers);
+#ifdef ANDROID_FIX
+ env->DeleteLocalRef(modifierClass);
+#endif
+}
+
+JavaMethod::~JavaMethod()
+{
+ if (_signature)
+ free(_signature);
+ delete [] _parameters;
+};
+
+// JNI method signatures use '/' between components of a class name, but
+// we get '.' between components from the reflection API.
+static void appendClassName(UString& aString, const char* className)
+{
+ ASSERT(JSLock::lockCount() > 0);
+
+ char *result, *cp = strdup(className);
+
+ result = cp;
+ while (*cp) {
+ if (*cp == '.')
+ *cp = '/';
+ cp++;
+ }
+
+ aString.append(result);
+
+ free (result);
+}
+
+const char *JavaMethod::signature() const
+{
+ if (!_signature) {
+ JSLock lock(false);
+
+ UString signatureBuilder("(");
+ for (int i = 0; i < _numParameters; i++) {
+ JavaParameter* aParameter = parameterAt(i);
+ JNIType _JNIType = aParameter->getJNIType();
+ if (_JNIType == array_type)
+ appendClassName(signatureBuilder, aParameter->type());
+ else {
+ signatureBuilder.append(signatureFromPrimitiveType(_JNIType));
+ if (_JNIType == object_type) {
+ appendClassName(signatureBuilder, aParameter->type());
+ signatureBuilder.append(";");
+ }
+ }
+ }
+ signatureBuilder.append(")");
+
+ const char *returnType = _returnType.UTF8String();
+ if (_JNIReturnType == array_type) {
+ appendClassName(signatureBuilder, returnType);
+ } else {
+ signatureBuilder.append(signatureFromPrimitiveType(_JNIReturnType));
+ if (_JNIReturnType == object_type) {
+ appendClassName(signatureBuilder, returnType);
+ signatureBuilder.append(";");
+ }
+ }
+
+ _signature = strdup(signatureBuilder.ascii());
+ }
+
+ return _signature;
+}
+
+JNIType JavaMethod::JNIReturnType() const
+{
+ return _JNIReturnType;
+}
+
+jmethodID JavaMethod::methodID (jobject obj) const
+{
+ if (_methodID == 0) {
+ _methodID = getMethodID (obj, _name.UTF8String(), signature());
+ }
+ return _methodID;
+}
+
+
diff --git a/V8Binding/jni/jni_runtime.h b/V8Binding/jni/jni_runtime.h
new file mode 100644
index 0000000..932f26b
--- /dev/null
+++ b/V8Binding/jni/jni_runtime.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _JNI_RUNTIME_H_
+#define _JNI_RUNTIME_H_
+
+#include "jni_utility.h"
+#include "jni_instance.h"
+
+#include "CString.h"
+
+namespace JSC
+{
+
+namespace Bindings
+{
+
+class JavaString
+{
+public:
+ JavaString() { }
+
+ void _commonInit (JNIEnv *e, jstring s)
+ {
+ int size = e->GetStringLength(s);
+ const char* cs = getCharactersFromJStringInEnv(e, s);
+ {
+ _utf8String = WebCore::CString(cs, size);
+ }
+ releaseCharactersForJStringInEnv (e, s, cs);
+ }
+
+ JavaString (JNIEnv *e, jstring s) {
+ _commonInit (e, s);
+ }
+
+ JavaString (jstring s) {
+ _commonInit (getJNIEnv(), s);
+ }
+
+ ~JavaString() { }
+
+ int length() const { return _utf8String->length(); }
+
+ const char* UTF8String() const {
+ return _utf8String.c_str();
+ }
+
+private:
+ WebCore::CString _utf8String;
+};
+
+class JavaParameter
+{
+public:
+ JavaParameter () : _JNIType(invalid_type) {};
+ JavaParameter (JNIEnv *env, jstring type);
+ virtual ~JavaParameter() { }
+
+ const char* type() const { return _type.UTF8String(); }
+ JNIType getJNIType() const { return _JNIType; }
+
+private:
+ JavaString _type;
+ JNIType _JNIType;
+};
+
+
+class JavaMethod
+{
+public:
+ JavaMethod(JNIEnv* env, jobject aMethod);
+ ~JavaMethod();
+
+ const char* name() const { return _name.UTF8String(); }
+ const char* returnType() const { return _returnType.UTF8String(); };
+ JavaParameter* parameterAt(int i) const { return &_parameters[i]; };
+ int numParameters() const { return _numParameters; };
+
+ const char *signature() const;
+ JNIType JNIReturnType() const;
+
+ jmethodID methodID (jobject obj) const;
+
+ bool isStatic() const { return _isStatic; }
+
+private:
+ JavaParameter* _parameters;
+ int _numParameters;
+ JavaString _name;
+ mutable char* _signature;
+ JavaString _returnType;
+ JNIType _JNIReturnType;
+ mutable jmethodID _methodID;
+ bool _isStatic;
+};
+
+} // namespace Bindings
+
+} // namespace JSC
+
+#endif // _JNI_RUNTIME_H_
diff --git a/V8Binding/jni/jni_utility.cpp b/V8Binding/jni/jni_utility.cpp
new file mode 100644
index 0000000..d86dd7b
--- /dev/null
+++ b/V8Binding/jni/jni_utility.cpp
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "jni_utility.h"
+#include "jni_runtime.h"
+
+#include <dlfcn.h>
+
+namespace JSC {
+
+namespace Bindings {
+
+static jint KJS_GetCreatedJavaVMs(JavaVM** vmBuf, jsize bufLen, jsize* nVMs)
+{
+ static void* javaVMFramework = 0;
+ if (!javaVMFramework)
+ javaVMFramework = dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM", RTLD_LAZY);
+ if (!javaVMFramework)
+ return JNI_ERR;
+
+ static jint(*functionPointer)(JavaVM**, jsize, jsize *) = 0;
+ if (!functionPointer)
+ functionPointer = (jint(*)(JavaVM**, jsize, jsize *))dlsym(javaVMFramework, "JNI_GetCreatedJavaVMs");
+ if (!functionPointer)
+ return JNI_ERR;
+ return functionPointer(vmBuf, bufLen, nVMs);
+}
+
+static JavaVM *jvm = 0;
+
+// Provide the ability for an outside component to specify the JavaVM to use
+// If the jvm value is set, the getJavaVM function below will just return.
+// In getJNIEnv(), if AttachCurrentThread is called to a VM that is already
+// attached, the result is a no-op.
+void setJavaVM(JavaVM *javaVM)
+{
+ jvm = javaVM;
+}
+
+JavaVM *getJavaVM()
+{
+ if (jvm)
+ return jvm;
+
+ JavaVM *jvmArray[1];
+ jsize bufLen = 1;
+ jsize nJVMs = 0;
+ jint jniError = 0;
+
+ // Assumes JVM is already running ..., one per process
+ jniError = KJS_GetCreatedJavaVMs(jvmArray, bufLen, &nJVMs);
+ if ( jniError == JNI_OK && nJVMs > 0 ) {
+ jvm = jvmArray[0];
+ }
+ else
+ fprintf(stderr, "%s: JNI_GetCreatedJavaVMs failed, returned %ld\n", __PRETTY_FUNCTION__, (long)jniError);
+
+ return jvm;
+}
+
+JNIEnv* getJNIEnv()
+{
+ union {
+ JNIEnv* env;
+ void* dummy;
+ } u;
+ jint jniError = 0;
+
+ jniError = (getJavaVM())->AttachCurrentThread(&u.dummy, NULL);
+ if (jniError == JNI_OK)
+ return u.env;
+ else
+ fprintf(stderr, "%s: AttachCurrentThread failed, returned %ld\n", __PRETTY_FUNCTION__, (long)jniError);
+ return NULL;
+}
+
+jmethodID getMethodID (jobject obj, const char *name, const char *sig)
+{
+ JNIEnv *env = getJNIEnv();
+ jmethodID mid = 0;
+
+ if ( env != NULL) {
+ jclass cls = env->GetObjectClass(obj);
+ if ( cls != NULL ) {
+ mid = env->GetMethodID(cls, name, sig);
+ if (!mid) {
+ env->ExceptionClear();
+ mid = env->GetStaticMethodID(cls, name, sig);
+ if (!mid) {
+ env->ExceptionClear();
+ }
+ }
+ }
+ env->DeleteLocalRef(cls);
+ }
+ return mid;
+}
+
+const char *getCharactersFromJString (jstring aJString)
+{
+ return getCharactersFromJStringInEnv (getJNIEnv(), aJString);
+}
+
+void releaseCharactersForJString (jstring aJString, const char *s)
+{
+ releaseCharactersForJStringInEnv (getJNIEnv(), aJString, s);
+}
+
+const char *getCharactersFromJStringInEnv (JNIEnv *env, jstring aJString)
+{
+ jboolean isCopy;
+ const char *s = env->GetStringUTFChars((jstring)aJString, &isCopy);
+ if (!s) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ fprintf (stderr, "\n");
+ }
+ return s;
+}
+
+void releaseCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const char *s)
+{
+ env->ReleaseStringUTFChars (aJString, s);
+}
+
+const jchar *getUCharactersFromJStringInEnv (JNIEnv *env, jstring aJString)
+{
+ jboolean isCopy;
+ const jchar *s = env->GetStringChars((jstring)aJString, &isCopy);
+ if (!s) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ fprintf (stderr, "\n");
+ }
+ return s;
+}
+
+void releaseUCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const jchar *s)
+{
+ env->ReleaseStringChars (aJString, s);
+}
+
+JNIType JNITypeFromClassName(const char *name)
+{
+ JNIType type;
+
+ if (strcmp("byte",name) == 0)
+ type = byte_type;
+ else if (strcmp("short",name) == 0)
+ type = short_type;
+ else if (strcmp("int",name) == 0)
+ type = int_type;
+ else if (strcmp("long",name) == 0)
+ type = long_type;
+ else if (strcmp("float",name) == 0)
+ type = float_type;
+ else if (strcmp("double",name) == 0)
+ type = double_type;
+ else if (strcmp("char",name) == 0)
+ type = char_type;
+ else if (strcmp("boolean",name) == 0)
+ type = boolean_type;
+ else if (strcmp("void",name) == 0)
+ type = void_type;
+ else if ('[' == name[0])
+ type = array_type;
+ else
+ type = object_type;
+
+ return type;
+}
+
+const char *signatureFromPrimitiveType(JNIType type)
+{
+ switch (type){
+ case void_type:
+ return "V";
+
+ case array_type:
+ return "[";
+
+ case object_type:
+ return "L";
+
+ case boolean_type:
+ return "Z";
+
+ case byte_type:
+ return "B";
+
+ case char_type:
+ return "C";
+
+ case short_type:
+ return "S";
+
+ case int_type:
+ return "I";
+
+ case long_type:
+ return "J";
+
+ case float_type:
+ return "F";
+
+ case double_type:
+ return "D";
+
+ case invalid_type:
+ default:
+ break;
+ }
+ return "";
+}
+
+JNIType JNITypeFromPrimitiveType(char type)
+{
+ switch (type){
+ case 'V':
+ return void_type;
+
+ case 'L':
+ return object_type;
+
+ case '[':
+ return array_type;
+
+ case 'Z':
+ return boolean_type;
+
+ case 'B':
+ return byte_type;
+
+ case 'C':
+ return char_type;
+
+ case 'S':
+ return short_type;
+
+ case 'I':
+ return int_type;
+
+ case 'J':
+ return long_type;
+
+ case 'F':
+ return float_type;
+
+ case 'D':
+ return double_type;
+
+ default:
+ break;
+ }
+ return invalid_type;
+}
+
+jvalue getJNIField( jobject obj, JNIType type, const char *name, const char *signature)
+{
+ JavaVM *jvm = getJavaVM();
+ JNIEnv *env = getJNIEnv();
+ jvalue result;
+
+ bzero (&result, sizeof(jvalue));
+ if ( obj != NULL && jvm != NULL && env != NULL) {
+ jclass cls = env->GetObjectClass(obj);
+ if ( cls != NULL ) {
+ jfieldID field = env->GetFieldID(cls, name, signature);
+ if ( field != NULL ) {
+ switch (type) {
+ case array_type:
+ case object_type:
+ result.l = env->functions->GetObjectField(env, obj, field);
+ break;
+ case boolean_type:
+ result.z = env->functions->GetBooleanField(env, obj, field);
+ break;
+ case byte_type:
+ result.b = env->functions->GetByteField(env, obj, field);
+ break;
+ case char_type:
+ result.c = env->functions->GetCharField(env, obj, field);
+ break;
+ case short_type:
+ result.s = env->functions->GetShortField(env, obj, field);
+ break;
+ case int_type:
+ result.i = env->functions->GetIntField(env, obj, field);
+ break;
+ case long_type:
+ result.j = env->functions->GetLongField(env, obj, field);
+ break;
+ case float_type:
+ result.f = env->functions->GetFloatField(env, obj, field);
+ break;
+ case double_type:
+ result.d = env->functions->GetDoubleField(env, obj, field);
+ break;
+ default:
+ fprintf(stderr, "%s: invalid field type (%d)\n", __PRETTY_FUNCTION__, (int)type);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "%s: Could not find field: %s\n", __PRETTY_FUNCTION__, name);
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ fprintf (stderr, "\n");
+ }
+
+ env->DeleteLocalRef(cls);
+ }
+ else {
+ fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__);
+ }
+ }
+
+ return result;
+}
+
+
+jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char* javaClassName)
+{
+ jvalue result;
+ NPVariantType type = value->type;
+
+ switch (_JNIType){
+ case array_type:
+ case object_type: {
+ result.l = (jobject)0;
+
+ // First see if we have a Java instance.
+ if (type == NPVariantType_Object) {
+ NPObject* objectImp = NPVARIANT_TO_OBJECT(*value);
+ if (objectImp->_class == &JavaNPClass) {
+ JavaNPObject* imp = static_cast<JavaNPObject*>(objectImp);
+ JavaInstance *instance = imp->_instance;
+ if (instance)
+ result.l = instance->javaInstance();
+ }
+ }
+
+ // Now convert value to a string if the target type is a java.lang.string, and we're not
+ // converting from a Null.
+ if (result.l == 0 && strcmp(javaClassName, "java.lang.String") == 0) {
+#ifdef CONVERT_NULL_TO_EMPTY_STRING
+ if (type == NPVariantType_Null) {
+ JNIEnv *env = getJNIEnv();
+ jchar buf[2];
+ jobject javaString = env->functions->NewString (env, buf, 0);
+ result.l = javaString;
+ }
+ else
+#else
+ if (type == NPVariantType_String) {
+#endif
+ NPString src = NPVARIANT_TO_STRING(*variant);
+ JNIEnv *env = getJNIEnv();
+ jobject javaString = env->functions->NewStringUTF(env, src.UTF8Characters, src.UTF8Length);
+ result.l = javaString;
+ }
+ } else if (result.l == 0)
+ bzero (&result, sizeof(jvalue)); // Handle it the same as a void case
+ }
+ break;
+
+ case boolean_type: {
+ if (type == NPVariantType_Boolean)
+ result.z = NPVARIANT_TO_BOOLEAN(*value);
+ else
+ bzero(&result, sizeof(jvalue)); // as void case
+ }
+ break;
+
+ case byte_type: {
+ if (type == NPVariantType_Int32)
+ result.b = (byte)NPVARIANT_TO_INT32(*value);
+ else
+ bzero(&result, sizeof(jvalue));
+ }
+ break;
+
+ case char_type: {
+ if (type == NPVariantType_Int32)
+ result.c = (char)NPVARIANT_TO_INT32(*value);
+ else
+ bzero(&result, sizeof(jvalue));
+ }
+ break;
+
+ case short_type: {
+ if (type == NPVariantType_Int32)
+ result.s = (jshort)NPVARIANT_TO_INT32(*value);
+ else
+ bzero(&result, sizeof(jvalue));
+ }
+ break;
+
+ case int_type: {
+ if (type == NPVariantType_Int32)
+ result.i = (jint)NPVARIANT_TO_INT32(*value);
+ else
+ bzero(&result, sizeof(jvalue));
+ }
+ break;
+
+ case long_type: {
+ if (type == NPVariantType_Int32)
+ result.j = (jlong)NPVARIANT_TO_INT32(*value);
+ else if (type == NPVariantType_Double)
+ result.j = (jlong)NPVARIANT_TO_DOUBLE(*value);
+ else
+ bzero(&result, sizeof(jvalue));
+ }
+ break;
+
+ case float_type: {
+ if (type == NPVariantType_Int32)
+ result.j = (jfloat)NPVARIANT_TO_INT32(*value);
+ else if (type == NPVariantType_Double)
+ result.j = (jfloat)NPVARIANT_TO_DOUBLE(*value);
+ else
+ bzero(&result, sizeof(jvalue));
+ }
+ break;
+
+ case double_type: {
+ if (type == NPVariantType_Int32)
+ result.j = (jdouble)NPVARIANT_TO_INT32(*value);
+ else if (type == NPVariantType_Double)
+ result.j = (jdouble)NPVARIANT_TO_DOUBLE(*value);
+ else
+ bzero(&result, sizeof(jvalue));
+ }
+ break;
+
+ break;
+
+ case invalid_type:
+ default:
+ case void_type: {
+ bzero (&result, sizeof(jvalue));
+ }
+ break;
+ }
+ return result;
+}
+
+} // end of namespace Bindings
+
+} // end of namespace JSC
diff --git a/V8Binding/jni/jni_utility.h b/V8Binding/jni/jni_utility.h
new file mode 100644
index 0000000..28b0763
--- /dev/null
+++ b/V8Binding/jni/jni_utility.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _JNI_UTILITY_H_
+#define _JNI_UTILITY_H_
+
+#include <JavaVM/jni.h>
+
+// The order of these items can not be modified as they are tightly
+// bound with the JVM on Mac OSX. If new types need to be added, they
+// should be added to the end. It is used in jni_obc.mm when calling
+// through to the JVM. Newly added items need to be made compatible
+// in that file.
+typedef enum {
+ invalid_type = 0,
+ void_type,
+ object_type,
+ boolean_type,
+ byte_type,
+ char_type,
+ short_type,
+ int_type,
+ long_type,
+ float_type,
+ double_type,
+ array_type
+} JNIType;
+
+namespace JSC {
+
+namespace Bindings {
+
+class JavaParameter;
+
+const char *getCharactersFromJString(jstring aJString);
+void releaseCharactersForJString(jstring aJString, const char *s);
+
+const char *getCharactersFromJStringInEnv(JNIEnv *env, jstring aJString);
+void releaseCharactersForJStringInEnv(JNIEnv *env, jstring aJString, const char *s);
+const jchar *getUCharactersFromJStringInEnv(JNIEnv *env, jstring aJString);
+void releaseUCharactersForJStringInEnv(JNIEnv *env, jstring aJString, const jchar *s);
+
+JNIType JNITypeFromClassName(const char *name);
+JNIType JNITypeFromPrimitiveType(char type);
+const char *signatureFromPrimitiveType(JNIType type);
+
+jvalue convertNPVariantToJValue(NPVariant*, JNIType, const char* javaClassName);
+
+jvalue getJNIField(jobject obj, JNIType type, const char *name, const char *signature);
+
+jmethodID getMethodID(jobject obj, const char *name, const char *sig);
+JNIEnv* getJNIEnv();
+JavaVM* getJavaVM();
+void setJavaVM(JavaVM*);
+
+
+template <typename T> struct JNICaller;
+
+template<> struct JNICaller<void> {
+ static void callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallVoidMethodA(obj, mid, args);
+ }
+ static void callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallVoidMethodV(obj, mid, args);
+ }
+};
+
+template<> struct JNICaller<jobject> {
+ static jobject callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallObjectMethodA(obj, mid, args);
+ }
+ static jobject callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallObjectMethodV(obj, mid, args);
+ }
+};
+
+template<> struct JNICaller<jboolean> {
+ static jboolean callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallBooleanMethodA(obj, mid, args);
+ }
+ static jboolean callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallBooleanMethodV(obj, mid, args);
+ }
+ static jboolean callStaticV(jclass cls, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallStaticBooleanMethod(cls, mid, args);
+ }
+
+};
+
+template<> struct JNICaller<jbyte> {
+ static jbyte callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallByteMethodA(obj, mid, args);
+ }
+ static jbyte callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallByteMethodV(obj, mid, args);
+ }
+};
+
+template<> struct JNICaller<jchar> {
+ static jchar callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallCharMethodA(obj, mid, args);
+ }
+ static jchar callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallCharMethodV(obj, mid, args);
+ }
+};
+
+template<> struct JNICaller<jshort> {
+ static jshort callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallShortMethodA(obj, mid, args);
+ }
+ static jshort callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallShortMethodV(obj, mid, args);
+ }
+};
+
+template<> struct JNICaller<jint> {
+ static jint callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallIntMethodA(obj, mid, args);
+ }
+ static jint callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallIntMethodV(obj, mid, args);
+ }
+};
+
+template<> struct JNICaller<jlong> {
+ static jlong callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallLongMethodA(obj, mid, args);
+ }
+ static jlong callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallLongMethodV(obj, mid, args);
+ }
+};
+
+template<> struct JNICaller<jfloat> {
+ static jfloat callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallFloatMethodA(obj, mid, args);
+ }
+ static jfloat callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallFloatMethodV(obj, mid, args);
+ }
+};
+
+template<> struct JNICaller<jdouble> {
+ static jdouble callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallDoubleMethodA(obj, mid, args);
+ }
+ static jdouble callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return getJNIEnv()->CallDoubleMethodV(obj, mid, args);
+ }
+};
+
+template<typename T> T callJNIMethodIDA(jobject obj, jmethodID mid, jvalue *args)
+{
+ return JNICaller<T>::callA(obj, mid, args);
+}
+
+template<typename T>
+static T callJNIMethodV(jobject obj, const char *name, const char *sig, va_list args)
+{
+ JavaVM *jvm = getJavaVM();
+ JNIEnv *env = getJNIEnv();
+
+ if ( obj != NULL && jvm != NULL && env != NULL) {
+ jclass cls = env->GetObjectClass(obj);
+ if ( cls != NULL ) {
+ jmethodID mid = env->GetMethodID(cls, name, sig);
+ if ( mid != NULL )
+ {
+#ifdef ANDROID_FIX // Avoids references to cls without popping the local frame.
+ env->DeleteLocalRef(cls);
+#endif
+ return JNICaller<T>::callV(obj, mid, args);
+ }
+ else
+ {
+ fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, obj);
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ fprintf (stderr, "\n");
+ }
+
+ env->DeleteLocalRef(cls);
+ }
+ else {
+ fprintf(stderr, "%s: Could not find class for %p\n", __PRETTY_FUNCTION__, obj);
+ }
+ }
+
+ return 0;
+}
+
+template<typename T>
+T callJNIMethod(jobject obj, const char* methodName, const char* methodSignature, ...)
+{
+ va_list args;
+ va_start(args, methodSignature);
+
+ T result= callJNIMethodV<T>(obj, methodName, methodSignature, args);
+
+ va_end(args);
+
+ return result;
+}
+
+template<typename T>
+T callJNIStaticMethod(jclass cls, const char* methodName, const char* methodSignature, ...)
+{
+ JavaVM *jvm = getJavaVM();
+ JNIEnv *env = getJNIEnv();
+ va_list args;
+
+ va_start(args, methodSignature);
+
+ T result = 0;
+
+ if (cls != NULL && jvm != NULL && env != NULL) {
+ jmethodID mid = env->GetStaticMethodID(cls, methodName, methodSignature);
+ if (mid != NULL)
+ result = JNICaller<T>::callStaticV(cls, mid, args);
+ else {
+ fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, methodName, cls);
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ fprintf (stderr, "\n");
+ }
+ }
+
+ va_end(args);
+
+ return result;
+}
+
+} // namespace Bindings
+
+} // namespace JSC
+
+#endif // _JNI_UTILITY_H_
diff --git a/V8Binding/npapi/README b/V8Binding/npapi/README
new file mode 100644
index 0000000..0522ba2
--- /dev/null
+++ b/V8Binding/npapi/README
@@ -0,0 +1,3 @@
+Copy from WebCore/bridge.
+
+We only need npapi.h and npruntime.h. Chrome's version is also tied to Chromme codebase.
diff --git a/V8Binding/npapi/npapi.h b/V8Binding/npapi/npapi.h
new file mode 100644
index 0000000..43b701b
--- /dev/null
+++ b/V8Binding/npapi/npapi.h
@@ -0,0 +1,853 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /*
+ * Netscape client plug-in API spec
+ */
+
+
+#ifndef _NPAPI_H_
+#define _NPAPI_H_
+
+#ifdef INCLUDE_JAVA
+#include "jri.h" /* Java Runtime Interface */
+#else
+#define jref void *
+#define JRIEnv void
+#endif
+
+#ifdef _WIN32
+# ifndef XP_WIN
+# define XP_WIN 1
+# endif /* XP_WIN */
+#endif /* _WIN32 */
+
+#ifdef __MWERKS__
+# define _declspec __declspec
+# ifdef macintosh
+# ifndef XP_MAC
+# define XP_MAC 1
+# endif /* XP_MAC */
+# endif /* macintosh */
+# ifdef __INTEL__
+# undef NULL
+# ifndef XP_WIN
+# define XP_WIN 1
+# endif /* __INTEL__ */
+# endif /* XP_PC */
+#endif /* __MWERKS__ */
+
+#if defined(__APPLE_CC__) && !defined(__MACOS_CLASSIC__) && !defined(XP_UNIX)
+# define XP_MACOSX
+#endif
+
+#ifdef XP_MAC
+ #include <Quickdraw.h>
+ #include <Events.h>
+#endif
+
+#if defined(XP_MACOSX) && defined(__LP64__)
+#define NP_NO_QUICKDRAW
+#define NP_NO_CARBON
+#endif
+
+#ifdef XP_MACOSX
+ #include <ApplicationServices/ApplicationServices.h>
+ #include <OpenGL/OpenGL.h>
+#ifndef NP_NO_CARBON
+ #include <Carbon/Carbon.h>
+#endif
+#endif
+
+#ifdef XP_UNIX
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+ #include <stdio.h>
+#endif
+
+#ifdef XP_WIN
+ #include <windows.h>
+#endif
+
+/*----------------------------------------------------------------------*/
+/* Plugin Version Constants */
+/*----------------------------------------------------------------------*/
+
+#define NP_VERSION_MAJOR 0
+#define NP_VERSION_MINOR 24
+
+/*----------------------------------------------------------------------*/
+/* Definition of Basic Types */
+/*----------------------------------------------------------------------*/
+
+#ifndef _UINT16
+#define _UINT16
+typedef unsigned short uint16;
+#endif
+
+#ifndef _UINT32
+#define _UINT32
+#ifdef __LP64__
+typedef unsigned int uint32;
+#else /* __LP64__ */
+typedef unsigned long uint32;
+#endif /* __LP64__ */
+#endif
+
+#ifndef _INT16
+#define _INT16
+typedef short int16;
+#endif
+
+#ifndef _INT32
+#define _INT32
+#ifdef __LP64__
+typedef int int32;
+#else /* __LP64__ */
+typedef long int32;
+#endif /* __LP64__ */
+#endif
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef NULL
+#define NULL (0L)
+#endif
+
+typedef unsigned char NPBool;
+typedef int16 NPError;
+typedef int16 NPReason;
+typedef char* NPMIMEType;
+
+
+
+/*----------------------------------------------------------------------*/
+/* Structures and definitions */
+/*----------------------------------------------------------------------*/
+
+#if !defined(__LP64__)
+#if defined(XP_MAC) || defined(XP_MACOSX)
+#pragma options align=mac68k
+#endif
+#endif /* __LP64__ */
+
+/*
+ * NPP is a plug-in's opaque instance handle
+ */
+typedef struct _NPP
+{
+ void* pdata; /* plug-in private data */
+ void* ndata; /* netscape private data */
+} NPP_t;
+
+typedef NPP_t* NPP;
+
+
+typedef struct _NPStream
+{
+ void* pdata; /* plug-in private data */
+ void* ndata; /* netscape private data */
+ const char* url;
+ uint32 end;
+ uint32 lastmodified;
+ void* notifyData;
+ const char* headers; /* Response headers from host.
+ * Exists only for >= NPVERS_HAS_RESPONSE_HEADERS.
+ * Used for HTTP only; NULL for non-HTTP.
+ * Available from NPP_NewStream onwards.
+ * Plugin should copy this data before storing it.
+ * Includes HTTP status line and all headers,
+ * preferably verbatim as received from server,
+ * headers formatted as in HTTP ("Header: Value"),
+ * and newlines (\n, NOT \r\n) separating lines.
+ * Terminated by \n\0 (NOT \n\n\0). */
+} NPStream;
+
+
+typedef struct _NPByteRange
+{
+ int32 offset; /* negative offset means from the end */
+ uint32 length;
+ struct _NPByteRange* next;
+} NPByteRange;
+
+
+typedef struct _NPSavedData
+{
+ int32 len;
+ void* buf;
+} NPSavedData;
+
+
+typedef struct _NPRect
+{
+ uint16 top;
+ uint16 left;
+ uint16 bottom;
+ uint16 right;
+} NPRect;
+
+
+#ifdef XP_UNIX
+/*
+ * Unix specific structures and definitions
+ */
+
+/*
+ * Callback Structures.
+ *
+ * These are used to pass additional platform specific information.
+ */
+enum {
+ NP_SETWINDOW = 1,
+ NP_PRINT
+};
+
+typedef struct
+{
+ int32 type;
+} NPAnyCallbackStruct;
+
+typedef struct
+{
+ int32 type;
+ Display* display;
+ Visual* visual;
+ Colormap colormap;
+ unsigned int depth;
+} NPSetWindowCallbackStruct;
+
+typedef struct
+{
+ int32 type;
+ FILE* fp;
+} NPPrintCallbackStruct;
+
+#endif /* XP_UNIX */
+
+/*
+ * The following masks are applied on certain platforms to NPNV and
+ * NPPV selectors that pass around pointers to COM interfaces. Newer
+ * compilers on some platforms may generate vtables that are not
+ * compatible with older compilers. To prevent older plugins from
+ * not understanding a new browser's ABI, these masks change the
+ * values of those selectors on those platforms. To remain backwards
+ * compatible with differenet versions of the browser, plugins can
+ * use these masks to dynamically determine and use the correct C++
+ * ABI that the browser is expecting. This does not apply to Windows
+ * as Microsoft's COM ABI will likely not change.
+ */
+
+#define NP_ABI_GCC3_MASK 0x10000000
+/*
+ * gcc 3.x generated vtables on UNIX and OSX are incompatible with
+ * previous compilers.
+ */
+#if (defined (XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3))
+#define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK
+#else
+#define _NP_ABI_MIXIN_FOR_GCC3 0
+#endif
+
+#define NP_ABI_MACHO_MASK 0x01000000
+/*
+ * On OSX, the Mach-O executable format is significantly
+ * different than CFM. In addition to having a different
+ * C++ ABI, it also has has different C calling convention.
+ * You must use glue code when calling between CFM and
+ * Mach-O C functions.
+ */
+#if (defined(TARGET_RT_MAC_MACHO))
+#define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK
+#else
+#define _NP_ABI_MIXIN_FOR_MACHO 0
+#endif
+
+
+#define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO)
+
+/*
+ * List of variable names for which NPP_GetValue shall be implemented
+ */
+typedef enum {
+ NPPVpluginNameString = 1,
+ NPPVpluginDescriptionString,
+ NPPVpluginWindowBool,
+ NPPVpluginTransparentBool,
+
+ NPPVjavaClass, /* Not implemented in WebKit */
+ NPPVpluginWindowSize, /* Not implemented in WebKit */
+ NPPVpluginTimerInterval, /* Not implemented in WebKit */
+
+ NPPVpluginScriptableInstance = (10 | NP_ABI_MASK), /* Not implemented in WebKit */
+ NPPVpluginScriptableIID = 11, /* Not implemented in WebKit */
+
+ /* 12 and over are available on Mozilla builds starting with 0.9.9 */
+ NPPVjavascriptPushCallerBool = 12, /* Not implemented in WebKit */
+ NPPVpluginKeepLibraryInMemory = 13, /* Not implemented in WebKit */
+ NPPVpluginNeedsXEmbed = 14, /* Not implemented in WebKit */
+
+ /* Get the NPObject for scripting the plugin. */
+ NPPVpluginScriptableNPObject = 15,
+
+ /* Get the plugin value (as \0-terminated UTF-8 string data) for
+ * form submission if the plugin is part of a form. Use
+ * NPN_MemAlloc() to allocate memory for the string data.
+ */
+ NPPVformValue = 16, /* Not implemented in WebKit */
+
+ NPPVpluginUrlRequestsDisplayedBool = 17, /* Not implemented in WebKit */
+
+ /* Checks if the plugin is interested in receiving the http body of
+ * failed http requests (http status != 200).
+ */
+ NPPVpluginWantsAllNetworkStreams = 18,
+
+ NPPVpluginPrivateModeBool = 19,
+
+ /* Checks to see if the plug-in would like the browser to load the "src" attribute. */
+ NPPVpluginCancelSrcStream = 20,
+
+#ifdef XP_MACOSX
+ /* Used for negotiating drawing models */
+ NPPVpluginDrawingModel = 1000,
+ /* Used for negotiating event models */
+ NPPVpluginEventModel = 1001,
+ /* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */
+ NPPVpluginCoreAnimationLayer = 1003
+#endif
+
+#ifdef ANDROID
+ NPPFakeValueToForce32Bits = 0x7FFFFFFF
+#endif
+} NPPVariable;
+
+/*
+ * List of variable names for which NPN_GetValue is implemented by Mozilla
+ */
+typedef enum {
+ NPNVxDisplay = 1,
+ NPNVxtAppContext,
+ NPNVnetscapeWindow,
+ NPNVjavascriptEnabledBool,
+ NPNVasdEnabledBool,
+ NPNVisOfflineBool,
+
+ /* 10 and over are available on Mozilla builds starting with 0.9.4 */
+ NPNVserviceManager = (10 | NP_ABI_MASK), /* Not implemented in WebKit */
+ NPNVDOMElement = (11 | NP_ABI_MASK), /* Not implemented in WebKit */
+ NPNVDOMWindow = (12 | NP_ABI_MASK), /* Not implemented in WebKit */
+ NPNVToolkit = (13 | NP_ABI_MASK), /* Not implemented in WebKit */
+ NPNVSupportsXEmbedBool = 14, /* Not implemented in WebKit */
+
+ /* Get the NPObject wrapper for the browser window. */
+ NPNVWindowNPObject = 15,
+
+ /* Get the NPObject wrapper for the plugins DOM element. */
+ NPNVPluginElementNPObject = 16,
+
+ NPNVSupportsWindowless = 17,
+
+ NPNVprivateModeBool = 18
+
+#ifdef XP_MACOSX
+ , NPNVpluginDrawingModel = 1000 /* The NPDrawingModel specified by the plugin */
+
+#ifndef NP_NO_QUICKDRAW
+ , NPNVsupportsQuickDrawBool = 2000 /* TRUE if the browser supports the QuickDraw drawing model */
+#endif
+ , NPNVsupportsCoreGraphicsBool = 2001 /* TRUE if the browser supports the CoreGraphics drawing model */
+ , NPNVsupportsOpenGLBool = 2002 /* TRUE if the browser supports the OpenGL drawing model (CGL on Mac) */
+ , NPNVsupportsCoreAnimationBool = 2003 /* TRUE if the browser supports the CoreAnimation drawing model */
+
+#ifndef NP_NO_CARBON
+ , NPNVsupportsCarbonBool = 3000 /* TRUE if the browser supports the Carbon event model */
+#endif
+ , NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
+
+#endif /* XP_MACOSX */
+
+#ifdef ANDROID
+ , NPNFakeValueToForce32Bits = 0x7FFFFFFF
+#endif
+} NPNVariable;
+
+typedef enum {
+ NPNURLVCookie = 501,
+ NPNURLVProxy
+} NPNURLVariable;
+
+/*
+ * The type of a NPWindow - it specifies the type of the data structure
+ * returned in the window field.
+ */
+typedef enum {
+ NPWindowTypeWindow = 1,
+ NPWindowTypeDrawable
+} NPWindowType;
+
+#ifdef XP_MACOSX
+
+/*
+ * The drawing model for a Mac OS X plugin. These are the possible values for the NPNVpluginDrawingModel variable.
+ */
+
+typedef enum {
+#ifndef NP_NO_QUICKDRAW
+ NPDrawingModelQuickDraw = 0,
+#endif
+ NPDrawingModelCoreGraphics = 1,
+ NPDrawingModelOpenGL = 2,
+ NPDrawingModelCoreAnimation = 3
+} NPDrawingModel;
+
+/*
+ * The event model for a Mac OS X plugin. These are the possible values for the NPNVpluginEventModel variable.
+ */
+
+typedef enum {
+#ifndef NP_NO_CARBON
+ NPEventModelCarbon = 0,
+#endif
+ NPEventModelCocoa = 1,
+} NPEventModel;
+
+typedef enum {
+ NPCocoaEventDrawRect = 1,
+ NPCocoaEventMouseDown,
+ NPCocoaEventMouseUp,
+ NPCocoaEventMouseMoved,
+ NPCocoaEventMouseEntered,
+ NPCocoaEventMouseExited,
+ NPCocoaEventMouseDragged,
+ NPCocoaEventKeyDown,
+ NPCocoaEventKeyUp,
+ NPCocoaEventFlagsChanged,
+ NPCocoaEventFocusChanged,
+ NPCocoaEventWindowFocusChanged,
+ NPCocoaEventScrollWheel,
+ NPCocoaEventTextInput
+} NPCocoaEventType;
+
+typedef struct _NPNSString NPNSString;
+typedef struct _NPNSWindow NPNSWindow;
+typedef struct _NPNSMenu NPNSMenu;
+
+typedef struct _NPCocoaEvent {
+ NPCocoaEventType type;
+ uint32 version;
+
+ union {
+ struct {
+ uint32 modifierFlags;
+ double pluginX;
+ double pluginY;
+ int32 buttonNumber;
+ int32 clickCount;
+ double deltaX;
+ double deltaY;
+ double deltaZ;
+ } mouse;
+ struct {
+ uint32 modifierFlags;
+ NPNSString *characters;
+ NPNSString *charactersIgnoringModifiers;
+ NPBool isARepeat;
+ uint16 keyCode;
+ } key;
+ struct {
+ double x;
+ double y;
+ double width;
+ double height;
+ } draw;
+ struct {
+ NPBool hasFocus;
+ } focus;
+ struct {
+ NPNSString *text;
+ } text;
+ } data;
+} NPCocoaEvent;
+
+#endif
+
+typedef struct _NPWindow
+{
+ void* window; /* Platform specific window handle */
+ int32 x; /* Position of top left corner relative */
+ int32 y; /* to a netscape page. */
+ uint32 width; /* Maximum window size */
+ uint32 height;
+ NPRect clipRect; /* Clipping rectangle in port coordinates */
+ /* Used by MAC only. */
+#ifdef XP_UNIX
+ void * ws_info; /* Platform-dependent additonal data */
+#endif /* XP_UNIX */
+ NPWindowType type; /* Is this a window or a drawable? */
+} NPWindow;
+
+
+typedef struct _NPFullPrint
+{
+ NPBool pluginPrinted; /* Set TRUE if plugin handled fullscreen */
+ /* printing */
+ NPBool printOne; /* TRUE if plugin should print one copy */
+ /* to default printer */
+ void* platformPrint; /* Platform-specific printing info */
+} NPFullPrint;
+
+typedef struct _NPEmbedPrint
+{
+ NPWindow window;
+ void* platformPrint; /* Platform-specific printing info */
+} NPEmbedPrint;
+
+typedef struct _NPPrint
+{
+ uint16 mode; /* NP_FULL or NP_EMBED */
+ union
+ {
+ NPFullPrint fullPrint; /* if mode is NP_FULL */
+ NPEmbedPrint embedPrint; /* if mode is NP_EMBED */
+ } print;
+} NPPrint;
+
+#ifdef XP_MACOSX
+typedef NPNSMenu NPMenu;
+#else
+typedef void * NPMenu;
+#endif
+
+#if defined(XP_MAC) || defined(XP_MACOSX)
+
+#ifndef NP_NO_CARBON
+typedef EventRecord NPEvent;
+#endif
+
+#elif defined(XP_WIN)
+typedef struct _NPEvent
+{
+ uint16 event;
+ uint32 wParam;
+ uint32 lParam;
+} NPEvent;
+#elif defined (XP_UNIX)
+typedef XEvent NPEvent;
+#else
+typedef void* NPEvent;
+#endif /* XP_MAC */
+
+#if defined(XP_MAC)
+typedef RgnHandle NPRegion;
+#elif defined(XP_MACOSX)
+/*
+ * NPRegion's type depends on the drawing model specified by the plugin (see NPNVpluginDrawingModel).
+ * NPQDRegion represents a QuickDraw RgnHandle and is used with the QuickDraw drawing model.
+ * NPCGRegion repesents a graphical region when using any other drawing model.
+ */
+typedef void *NPRegion;
+#ifndef NP_NO_QUICKDRAW
+typedef RgnHandle NPQDRegion;
+#endif
+typedef CGPathRef NPCGRegion;
+#elif defined(XP_WIN)
+typedef HRGN NPRegion;
+#elif defined(XP_UNIX)
+typedef Region NPRegion;
+#else
+typedef void *NPRegion;
+#endif /* XP_MAC */
+
+#ifdef XP_MACOSX
+
+/*
+ * NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics
+ * as its drawing model.
+ */
+
+typedef struct NP_CGContext
+{
+ CGContextRef context;
+#ifdef NP_NO_CARBON
+ NPNSWindow *window;
+#else
+ void *window; // Can be either an NSWindow or a WindowRef depending on the event model
+#endif
+} NP_CGContext;
+
+/*
+ * NP_GLContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelOpenGL as its
+ * drawing model.
+ */
+
+typedef struct NP_GLContext
+{
+ CGLContextObj context;
+#ifdef NP_NO_CARBON
+ NPNSWindow *window;
+#else
+ void *window; // Can be either an NSWindow or a WindowRef depending on the event model
+#endif
+} NP_GLContext;
+
+#endif /* XP_MACOSX */
+
+#if defined(XP_MAC) || defined(XP_MACOSX)
+
+/*
+ * Mac-specific structures and definitions.
+ */
+
+#ifndef NP_NO_QUICKDRAW
+
+/*
+ * NP_Port is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelQuickDraw as its
+ * drawing model, or the plugin does not specify a drawing model.
+ *
+ * It is not recommended that new plugins use NPDrawingModelQuickDraw or NP_Port, as QuickDraw has been
+ * deprecated in Mac OS X 10.5. CoreGraphics is the preferred drawing API.
+ *
+ * NP_Port is not available in 64-bit.
+ */
+
+typedef struct NP_Port
+{
+ CGrafPtr port; /* Grafport */
+ int32 portx; /* position inside the topmost window */
+ int32 porty;
+} NP_Port;
+
+#endif /* NP_NO_QUICKDRAW */
+
+/*
+ * Non-standard event types that can be passed to HandleEvent
+ */
+#define getFocusEvent (osEvt + 16)
+#define loseFocusEvent (osEvt + 17)
+#define adjustCursorEvent (osEvt + 18)
+
+#endif /* XP_MAC */
+
+
+/*
+ * Values for mode passed to NPP_New:
+ */
+#define NP_EMBED 1
+#define NP_FULL 2
+
+/*
+ * Values for stream type passed to NPP_NewStream:
+ */
+#define NP_NORMAL 1
+#define NP_SEEK 2
+#define NP_ASFILE 3
+#define NP_ASFILEONLY 4
+
+#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)
+
+#if !defined(__LP64__)
+#if defined(XP_MAC) || defined(XP_MACOSX)
+#pragma options align=reset
+#endif
+#endif /* __LP64__ */
+
+
+/*----------------------------------------------------------------------*/
+/* Error and Reason Code definitions */
+/*----------------------------------------------------------------------*/
+
+/*
+ * Values of type NPError:
+ */
+#define NPERR_BASE 0
+#define NPERR_NO_ERROR (NPERR_BASE + 0)
+#define NPERR_GENERIC_ERROR (NPERR_BASE + 1)
+#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2)
+#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3)
+#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4)
+#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5)
+#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6)
+#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7)
+#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8)
+#define NPERR_INVALID_PARAM (NPERR_BASE + 9)
+#define NPERR_INVALID_URL (NPERR_BASE + 10)
+#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11)
+#define NPERR_NO_DATA (NPERR_BASE + 12)
+#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13)
+
+/*
+ * Values of type NPReason:
+ */
+#define NPRES_BASE 0
+#define NPRES_DONE (NPRES_BASE + 0)
+#define NPRES_NETWORK_ERR (NPRES_BASE + 1)
+#define NPRES_USER_BREAK (NPRES_BASE + 2)
+
+/*
+ * Don't use these obsolete error codes any more.
+ */
+#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR
+#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR
+#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK
+
+/*
+ * Version feature information
+ */
+#define NPVERS_HAS_STREAMOUTPUT 8
+#define NPVERS_HAS_NOTIFICATION 9
+#define NPVERS_HAS_LIVECONNECT 9
+#define NPVERS_WIN16_HAS_LIVECONNECT 9
+#define NPVERS_68K_HAS_LIVECONNECT 11
+#define NPVERS_HAS_WINDOWLESS 11
+#define NPVERS_HAS_XPCONNECT_SCRIPTING 13 /* Not implemented in WebKit */
+#define NPVERS_HAS_NPRUNTIME_SCRIPTING 14
+#define NPVERS_HAS_FORM_VALUES 15 /* Not implemented in WebKit; see bug 13061 */
+#define NPVERS_HAS_POPUPS_ENABLED_STATE 16 /* Not implemented in WebKit */
+#define NPVERS_HAS_RESPONSE_HEADERS 17
+#define NPVERS_HAS_NPOBJECT_ENUM 18
+#define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19
+#define NPVERS_HAS_ALL_NETWORK_STREAMS 20
+#define NPVERS_HAS_URL_AND_AUTH_INFO 21
+#define NPVERS_HAS_PRIVATE_MODE 22
+#define NPVERS_MACOSX_HAS_EVENT_MODELS 23
+#define NPVERS_HAS_CANCEL_SRC_STREAM 24
+
+/*----------------------------------------------------------------------*/
+/* Function Prototypes */
+/*----------------------------------------------------------------------*/
+
+#if defined(_WINDOWS) && !defined(WIN32)
+#define NP_LOADDS _loadds
+#else
+#define NP_LOADDS
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * NPP_* functions are provided by the plugin and called by the navigator.
+ */
+
+#ifdef XP_UNIX
+char* NPP_GetMIMEDescription(void);
+#endif /* XP_UNIX */
+
+NPError NPP_Initialize(void);
+void NPP_Shutdown(void);
+NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
+ uint16 mode, int16 argc, char* argn[],
+ char* argv[], NPSavedData* saved);
+NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);
+NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);
+NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
+ NPStream* stream, NPBool seekable,
+ uint16* stype);
+NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
+ NPReason reason);
+int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);
+int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset,
+ int32 len, void* buffer);
+void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
+ const char* fname);
+void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);
+int16 NPP_HandleEvent(NPP instance, void* event);
+void NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
+ NPReason reason, void* notifyData);
+jref NP_LOADDS NPP_GetJavaClass(void);
+NPError NPP_GetValue(NPP instance, NPPVariable variable,
+ void *value);
+NPError NPP_SetValue(NPP instance, NPNVariable variable,
+ void *value);
+
+/*
+ * NPN_* functions are provided by the navigator and called by the plugin.
+ */
+
+void NPN_Version(int* plugin_major, int* plugin_minor,
+ int* netscape_major, int* netscape_minor);
+NPError NPN_GetURLNotify(NPP instance, const char* url,
+ const char* target, void* notifyData);
+NPError NPN_GetURL(NPP instance, const char* url,
+ const char* target);
+NPError NPN_PostURLNotify(NPP instance, const char* url,
+ const char* target, uint32 len,
+ const char* buf, NPBool file,
+ void* notifyData);
+NPError NPN_PostURL(NPP instance, const char* url,
+ const char* target, uint32 len,
+ const char* buf, NPBool file);
+NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);
+NPError NPN_NewStream(NPP instance, NPMIMEType type,
+ const char* target, NPStream** stream);
+int32 NPN_Write(NPP instance, NPStream* stream, int32 len,
+ void* buffer);
+NPError NPN_DestroyStream(NPP instance, NPStream* stream,
+ NPReason reason);
+void NPN_Status(NPP instance, const char* message);
+const char* NPN_UserAgent(NPP instance);
+void* NPN_MemAlloc(uint32 size);
+void NPN_MemFree(void* ptr);
+uint32 NPN_MemFlush(uint32 size);
+void NPN_ReloadPlugins(NPBool reloadPages);
+JRIEnv* NPN_GetJavaEnv(void);
+jref NPN_GetJavaPeer(NPP instance);
+NPError NPN_GetValue(NPP instance, NPNVariable variable,
+ void *value);
+NPError NPN_SetValue(NPP instance, NPPVariable variable,
+ void *value);
+void NPN_InvalidateRect(NPP instance, NPRect *invalidRect);
+void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion);
+void NPN_ForceRedraw(NPP instance);
+void NPN_PushPopupsEnabledState(NPP instance, NPBool enabled);
+void NPN_PopPopupsEnabledState(NPP instance);
+void NPN_PluginThreadAsyncCall(NPP instance, void (*func) (void *), void *userData);
+uint32 NPN_ScheduleTimer(NPP instance, uint32 interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32 timerID));
+void NPN_UnscheduleTimer(NPP instance, uint32 timerID);
+NPError NPN_PopUpContextMenu(NPP instance, NPMenu* menu);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif /* _NPAPI_H_ */
diff --git a/V8Binding/npapi/npruntime.h b/V8Binding/npapi/npruntime.h
new file mode 100644
index 0000000..8a285be
--- /dev/null
+++ b/V8Binding/npapi/npruntime.h
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2004, Apple Computer, Inc. and The Mozilla Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla
+ * Foundation ("Mozilla") nor the names of their contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR
+ * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Revision 1 (March 4, 2004):
+ * Initial proposal.
+ *
+ * Revision 2 (March 10, 2004):
+ * All calls into script were made asynchronous. Results are
+ * provided via the NPScriptResultFunctionPtr callback.
+ *
+ * Revision 3 (March 10, 2004):
+ * Corrected comments to not refer to class retain/release FunctionPtrs.
+ *
+ * Revision 4 (March 11, 2004):
+ * Added additional convenience NPN_SetExceptionWithUTF8().
+ * Changed NPHasPropertyFunctionPtr and NPHasMethodFunctionPtr to take NPClass
+ * pointers instead of NPObject pointers.
+ * Added NPIsValidIdentifier().
+ *
+ * Revision 5 (March 17, 2004):
+ * Added context parameter to result callbacks from ScriptObject functions.
+ *
+ * Revision 6 (March 29, 2004):
+ * Renamed functions implemented by user agent to NPN_*. Removed _ from
+ * type names.
+ * Renamed "JavaScript" types to "Script".
+ *
+ * Revision 7 (April 21, 2004):
+ * NPIdentifier becomes a void*, was int32_t
+ * Remove NP_IsValidIdentifier, renamed NP_IdentifierFromUTF8 to NP_GetIdentifier
+ * Added NPVariant and modified functions to use this new type.
+ *
+ * Revision 8 (July 9, 2004):
+ * Updated to joint Apple-Mozilla license.
+ *
+ * Revision 9 (August 12, 2004):
+ * Changed NPVariantType enum values to form PVariantType_XXX
+ * Added NPP arguments to NPObject functions.
+ * Replaced NPVariant functions with macros.
+ */
+#ifndef _NP_RUNTIME_H_
+#define _NP_RUNTIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "npapi.h"
+
+/*
+ This API is used to facilitate binding code written in C to script
+ objects. The API in this header does not assume the presence of a
+ user agent. That is, it can be used to bind C code to scripting
+ environments outside of the context of a user agent.
+
+ However, the normal use of the this API is in the context of a
+ scripting environment running in a browser or other user agent.
+ In particular it is used to support the extended Netscape
+ script-ability API for plugins (NP-SAP). NP-SAP is an extension
+ of the Netscape plugin API. As such we have adopted the use of
+ the "NP" prefix for this API.
+
+ The following NP{N|P}Variables were added to the Netscape plugin
+ API (in npapi.h):
+
+ NPNVWindowNPObject
+ NPNVPluginElementNPObject
+ NPPVpluginScriptableNPObject
+
+ These variables are exposed through NPN_GetValue() and
+ NPP_GetValue() (respectively) and are used to establish the
+ initial binding between the user agent and native code. The DOM
+ objects in the user agent can be examined and manipulated using
+ the NPN_ functions that operate on NPObjects described in this
+ header.
+
+ To the extent possible the assumptions about the scripting
+ language used by the scripting environment have been minimized.
+*/
+
+
+/*
+ Objects (non-primitive data) passed between 'C' and script is
+ always wrapped in an NPObject. The 'interface' of an NPObject is
+ described by an NPClass.
+*/
+typedef struct NPObject NPObject;
+typedef struct NPClass NPClass;
+
+typedef char NPUTF8;
+typedef struct _NPString {
+ const NPUTF8 *UTF8Characters;
+ uint32_t UTF8Length;
+} NPString;
+
+typedef enum {
+ NPVariantType_Void,
+ NPVariantType_Null,
+ NPVariantType_Bool,
+ NPVariantType_Int32,
+ NPVariantType_Double,
+ NPVariantType_String,
+ NPVariantType_Object
+} NPVariantType;
+
+typedef struct _NPVariant {
+ NPVariantType type;
+ union {
+ bool boolValue;
+ int32_t intValue;
+ double doubleValue;
+ NPString stringValue;
+ NPObject *objectValue;
+ } value;
+} NPVariant;
+
+/*
+ NPN_ReleaseVariantValue is called on all 'out' parameters references.
+ Specifically it is called on variants that are resultant out parameters
+ in NPGetPropertyFunctionPtr and NPInvokeFunctionPtr. Resultant variants
+ from these two functions should be initialized using the
+ NPN_InitializeVariantXXX() functions.
+
+ After calling NPReleaseVariantValue, the type of the variant will
+ be set to NPVariantUndefinedType.
+*/
+void NPN_ReleaseVariantValue (NPVariant *variant);
+
+#define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void)
+#define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null)
+#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)
+#define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32)
+#define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double)
+#define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String)
+#define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object)
+
+#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)
+#define NPVARIANT_TO_INT32(_v) ((_v).value.intValue)
+#define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue)
+#define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue)
+#define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue)
+
+#define NP_BEGIN_MACRO do {
+#define NP_END_MACRO } while (0)
+
+#define VOID_TO_NPVARIANT(_v) NP_BEGIN_MACRO (_v).type = NPVariantType_Void; (_v).value.objectValue = NULL; NP_END_MACRO
+#define NULL_TO_NPVARIANT(_v) NP_BEGIN_MACRO (_v).type = NPVariantType_Null; (_v).value.objectValue = NULL; NP_END_MACRO
+#define BOOLEAN_TO_NPVARIANT(_val, _v) NP_BEGIN_MACRO (_v).type = NPVariantType_Bool; (_v).value.boolValue = !!(_val); NP_END_MACRO
+#define INT32_TO_NPVARIANT(_val, _v) NP_BEGIN_MACRO (_v).type = NPVariantType_Int32; (_v).value.intValue = _val; NP_END_MACRO
+#define DOUBLE_TO_NPVARIANT(_val, _v) NP_BEGIN_MACRO (_v).type = NPVariantType_Double; (_v).value.doubleValue = _val; NP_END_MACRO
+#define STRINGZ_TO_NPVARIANT(_val, _v) NP_BEGIN_MACRO (_v).type = NPVariantType_String; NPString str = { _val, strlen(_val) }; (_v).value.stringValue = str; NP_END_MACRO
+#define STRINGN_TO_NPVARIANT(_val, _len, _v) NP_BEGIN_MACRO (_v).type = NPVariantType_String; NPString str = { _val, _len }; (_v).value.stringValue = str; NP_END_MACRO
+#define OBJECT_TO_NPVARIANT(_val, _v) NP_BEGIN_MACRO (_v).type = NPVariantType_Object; (_v).value.objectValue = _val; NP_END_MACRO
+
+/*
+ Type mappings (JavaScript types have been used for illustration
+ purposes):
+
+ JavaScript to C (NPVariant with type:)
+ undefined NPVariantType_Void
+ null NPVariantType_Null
+ Boolean NPVariantType_Bool
+ Number NPVariantType_Double or NPVariantType_Int32
+ String NPVariantType_String
+ Object NPVariantType_Object
+
+ C (NPVariant with type:) to JavaScript
+ NPVariantType_Void undefined
+ NPVariantType_Null null
+ NPVariantType_Bool Boolean
+ NPVariantType_Int32 Number
+ NPVariantType_Double Number
+ NPVariantType_String String
+ NPVariantType_Object Object
+*/
+
+typedef void *NPIdentifier;
+
+/*
+ NPObjects have methods and properties. Methods and properties are
+ identified with NPIdentifiers. These identifiers may be reflected
+ in script. NPIdentifiers can be either strings or integers, IOW,
+ methods and properties can be identified by either strings or
+ integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be
+ compared using ==. In case of any errors, the requested
+ NPIdentifier(s) will be NULL.
+*/
+NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name);
+void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers);
+NPIdentifier NPN_GetIntIdentifier(int32_t intid);
+bool NPN_IdentifierIsString(NPIdentifier identifier);
+
+/*
+ The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.
+*/
+NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier);
+
+/*
+ Get the integer represented by identifier. If identifier is not an
+ integer identifier, the behaviour is undefined.
+*/
+int32_t NPN_IntFromIdentifier(NPIdentifier identifier);
+
+/*
+ NPObject behavior is implemented using the following set of
+ callback functions.
+
+ The NPVariant *result argument of these functions (where
+ applicable) should be released using NPN_ReleaseVariantValue().
+*/
+typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);
+typedef void (*NPDeallocateFunctionPtr)(NPObject *obj);
+typedef void (*NPInvalidateFunctionPtr)(NPObject *obj);
+typedef bool (*NPHasMethodFunctionPtr)(NPObject *obj, NPIdentifier name);
+typedef bool (*NPInvokeFunctionPtr)(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
+typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result);
+typedef bool (*NPHasPropertyFunctionPtr)(NPObject *obj, NPIdentifier name);
+typedef bool (*NPGetPropertyFunctionPtr)(NPObject *obj, NPIdentifier name, NPVariant *result);
+typedef bool (*NPSetPropertyFunctionPtr)(NPObject *obj, NPIdentifier name, const NPVariant *value);
+typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);
+typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value, uint32_t *count);
+typedef bool (*NPConstructFunctionPtr)(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result);
+
+/*
+ NPObjects returned by create have a reference count of one. It is the caller's responsibility
+ to release the returned object.
+
+ NPInvokeFunctionPtr function may return false to indicate a the method could not be invoked.
+
+ NPGetPropertyFunctionPtr and NPSetPropertyFunctionPtr may return false to indicate a property doesn't
+ exist.
+
+ NPInvalidateFunctionPtr is called by the scripting environment when the native code is
+ shutdown. Any attempt to message a NPObject instance after the invalidate
+ callback has been called will result in undefined behavior, even if the
+ native code is still retaining those NPObject instances.
+ (The runtime will typically return immediately, with 0 or NULL, from an attempt to
+ dispatch to a NPObject, but this behavior should not be depended upon.)
+
+ The NPEnumerationFunctionPtr function may pass an array of
+ NPIdentifiers back to the caller. The callee allocs the memory of
+ the array using NPN_MemAlloc(), and it's the caller's responsibility
+ to release it using NPN_MemFree().
+*/
+struct NPClass
+{
+ uint32_t structVersion;
+ NPAllocateFunctionPtr allocate;
+ NPDeallocateFunctionPtr deallocate;
+ NPInvalidateFunctionPtr invalidate;
+ NPHasMethodFunctionPtr hasMethod;
+ NPInvokeFunctionPtr invoke;
+ NPInvokeDefaultFunctionPtr invokeDefault;
+ NPHasPropertyFunctionPtr hasProperty;
+ NPGetPropertyFunctionPtr getProperty;
+ NPSetPropertyFunctionPtr setProperty;
+ NPRemovePropertyFunctionPtr removeProperty;
+ NPEnumerationFunctionPtr enumerate;
+ NPConstructFunctionPtr construct;
+};
+
+#define NP_CLASS_STRUCT_VERSION 3
+#define NP_CLASS_STRUCT_VERSION_ENUM 2
+#define NP_CLASS_STRUCT_VERSION_CTOR 3
+
+#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \
+ ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)
+#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \
+ ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)
+
+struct NPObject {
+ NPClass *_class;
+ uint32_t referenceCount;
+ // Additional space may be allocated here by types of NPObjects
+};
+
+/*
+ If the class has an allocate function, NPN_CreateObject invokes that function,
+ otherwise a NPObject is allocated and returned. If a class has an allocate
+ function it is the responsibility of that implementation to set the initial retain
+ count to 1.
+*/
+NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);
+
+/*
+ Increment the NPObject's reference count.
+*/
+NPObject *NPN_RetainObject (NPObject *obj);
+
+/*
+ Decremented the NPObject's reference count. If the reference
+ count goes to zero, the class's destroy function is invoke if
+ specified, otherwise the object is freed directly.
+*/
+void NPN_ReleaseObject (NPObject *obj);
+
+/*
+ Functions to access script objects represented by NPObject.
+
+ Calls to script objects are synchronous. If a function returns a
+ value, it will be supplied via the result NPVariant
+ argument. Successful calls will return true, false will be
+ returned in case of an error.
+
+ Calls made from plugin code to script must be made from the thread
+ on which the plugin was initialized.
+*/
+bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);
+bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result);
+bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script, NPVariant *result);
+bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, NPVariant *result);
+bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, const NPVariant *value);
+bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
+bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);
+bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);
+bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count);
+bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result);
+
+/*
+ NPN_SetException may be called to trigger a script exception upon return
+ from entry points into NPObjects.
+*/
+void NPN_SetException (NPObject *obj, const NPUTF8 *message);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/V8Binding/scripts/CodeGenerator.pm b/V8Binding/scripts/CodeGenerator.pm
new file mode 100644
index 0000000..d115459
--- /dev/null
+++ b/V8Binding/scripts/CodeGenerator.pm
@@ -0,0 +1,334 @@
+#
+# KDOM IDL parser
+#
+# Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org>
+# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+#
+# This file is part of the KDE project
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# aint with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+package CodeGenerator;
+
+my $useDocument = "";
+my $useGenerator = "";
+my $useOutputDir = "";
+my $useDirectories = "";
+my $useLayerOnTop = 0;
+my $preprocessor;
+
+my $codeGenerator = 0;
+
+my $verbose = 0;
+
+my %primitiveTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1,
+ "unsigned int" => 1, "unsigned short" => 1,
+ "unsigned long" => 1, "float" => 1,
+ "unsigned long long" => 1,
+ "double" => 1, "boolean" => 1, "void" => 1);
+
+my %podTypeHash = ("SVGNumber" => 1, "SVGTransform" => 1);
+my %podTypeWithWriteablePropertiesHash = ("SVGLength" => 1, "SVGMatrix" => 1, "SVGPoint" => 1, "SVGRect" => 1);
+my %stringTypeHash = ("DOMString" => 1, "AtomicString" => 1);
+
+my %nonPointerTypeHash = ("DOMTimeStamp" => 1, "CompareHow" => 1, "SVGPaintType" => 1);
+
+my %svgAnimatedTypeHash = ("SVGAnimatedAngle" => 1, "SVGAnimatedBoolean" => 1,
+ "SVGAnimatedEnumeration" => 1, "SVGAnimatedInteger" => 1,
+ "SVGAnimatedLength" => 1, "SVGAnimatedLengthList" => 1,
+ "SVGAnimatedNumber" => 1, "SVGAnimatedNumberList" => 1,
+ "SVGAnimatedPreserveAspectRatio" => 1,
+ "SVGAnimatedRect" => 1, "SVGAnimatedString" => 1,
+ "SVGAnimatedTransformList" => 1);
+
+# Helpers for 'ScanDirectory'
+my $endCondition = 0;
+my $foundFilename = "";
+my @foundFilenames = ();
+my $ignoreParent = 1;
+my $defines = "";
+
+# Default constructor
+sub new
+{
+ my $object = shift;
+ my $reference = { };
+
+ $useDirectories = shift;
+ $useGenerator = shift;
+ $useOutputDir = shift;
+ $useLayerOnTop = shift;
+ $preprocessor = shift;
+
+ bless($reference, $object);
+ return $reference;
+}
+
+sub StripModule($)
+{
+ my $object = shift;
+ my $name = shift;
+ $name =~ s/[a-zA-Z0-9]*:://;
+ return $name;
+}
+
+sub ProcessDocument
+{
+ my $object = shift;
+ $useDocument = shift;
+ $defines = shift;
+
+ my $ifaceName = "CodeGenerator" . $useGenerator;
+
+ # Dynamically load external code generation perl module
+ require $ifaceName . ".pm";
+ $codeGenerator = $ifaceName->new($object, $useOutputDir, $useLayerOnTop, $preprocessor);
+ unless (defined($codeGenerator)) {
+ my $classes = $useDocument->classes;
+ foreach my $class (@$classes) {
+ print "Skipping $useGenerator code generation for IDL interface \"" . $class->name . "\".\n" if $verbose;
+ }
+ return;
+ }
+
+ # Start the actual code generation!
+ $codeGenerator->GenerateModule($useDocument, $defines);
+
+ my $classes = $useDocument->classes;
+ foreach my $class (@$classes) {
+ print "Generating $useGenerator bindings code for IDL interface \"" . $class->name . "\"...\n" if $verbose;
+ $codeGenerator->GenerateInterface($class, $defines);
+ $codeGenerator->finish();
+ }
+}
+
+
+sub FindParentsRecursively
+{
+ my $object = shift;
+ my $dataNode = shift;
+ my @parents = ($dataNode->name);
+ foreach (@{$dataNode->parents}) {
+ my $interface = $object->StripModule($_);
+
+ $endCondition = 0;
+ $foundFilename = "";
+ foreach (@{$useDirectories}) {
+ $object->ScanDirectory("$interface.idl", $_, $_, 0) if ($foundFilename eq "");
+ }
+
+ if ($foundFilename ne "") {
+ print " | |> Parsing parent IDL \"$foundFilename\" for interface \"$interface\"\n" if $verbose;
+
+ # Step #2: Parse the found IDL file (in quiet mode).
+ my $parser = IDLParser->new(1);
+ my $document = $parser->ParseInheritance($foundFilename, $defines, $preprocessor);
+
+ foreach my $class (@{$document->classes}) {
+ @parents = (@parents, FindParentsRecursively($object, $class));
+ }
+ } else {
+ die("Could NOT find specified parent interface \"$interface\"!\n")
+ }
+ }
+ return @parents;
+}
+
+
+sub AddMethodsConstantsAndAttributesFromParentClasses
+{
+ # For the passed interface, recursively parse all parent
+ # IDLs in order to find out all inherited properties/methods.
+
+ my $object = shift;
+ my $dataNode = shift;
+
+ my @parents = @{$dataNode->parents};
+ my $parentsMax = @{$dataNode->parents};
+
+ my $constantsRef = $dataNode->constants;
+ my $functionsRef = $dataNode->functions;
+ my $attributesRef = $dataNode->attributes;
+
+ # Exception: For the DOM 'Node' is our topmost baseclass, not EventTargetNode.
+ foreach (@{$dataNode->parents}) {
+ my $interface = $object->StripModule($_);
+
+ # Don't ignore the first class EventTarget
+ if ($interface ne "EventTarget" && $ignoreParent) {
+ # Ignore first parent class, already handled by the generation itself.
+ $ignoreParent = 0;
+ next;
+ }
+
+ # Step #1: Find the IDL file associated with 'interface'
+ $endCondition = 0;
+ $foundFilename = "";
+
+ foreach (@{$useDirectories}) {
+ $object->ScanDirectory("$interface.idl", $_, $_, 0) if ($foundFilename eq "");
+ }
+
+ if ($foundFilename ne "") {
+ print " | |> Parsing parent IDL \"$foundFilename\" for interface \"$interface\"\n" if $verbose;
+
+ # Step #2: Parse the found IDL file (in quiet mode).
+ my $parser = IDLParser->new(1);
+ my $document = $parser->Parse($foundFilename, $defines, $preprocessor);
+
+ foreach my $class (@{$document->classes}) {
+ # Step #3: Enter recursive parent search
+ AddMethodsConstantsAndAttributesFromParentClasses($object, $class);
+
+ # Step #4: Collect constants & functions & attributes of this parent-class
+ my $constantsMax = @{$class->constants};
+ my $functionsMax = @{$class->functions};
+ my $attributesMax = @{$class->attributes};
+
+ print " | |> -> Inheriting $constantsMax constants, $functionsMax functions, $attributesMax attributes...\n | |>\n" if $verbose;
+
+ # Step #5: Concatenate data
+ push(@$constantsRef, $_) foreach (@{$class->constants});
+ push(@$functionsRef, $_) foreach (@{$class->functions});
+ push(@$attributesRef, $_) foreach (@{$class->attributes});
+ }
+ } else {
+ die("Could NOT find specified parent interface \"$interface\"!\n");
+ }
+ }
+}
+
+# Append an attribute to an array if its name does not exist in the array.
+sub AppendAttribute
+{
+ my $attributes = shift;
+ my $newAttr = shift;
+ foreach (@$attributes) {
+ if ($_->signature->name eq $newAttr->signature->name) {
+ print " | |> -> $newAttr->signature->name is overridden.\n | |>\n" if $verbose;
+ return;
+ }
+ }
+ push(@$attributes, $newAttr);
+}
+
+# Helpers for all CodeGenerator***.pm modules
+sub IsPodType
+{
+ my $object = shift;
+ my $type = shift;
+
+ return 1 if $podTypeHash{$type};
+ return 1 if $podTypeWithWriteablePropertiesHash{$type};
+ return 0;
+}
+
+sub IsPodTypeWithWriteableProperties
+{
+ my $object = shift;
+ my $type = shift;
+
+ return 1 if $podTypeWithWriteablePropertiesHash{$type};
+ return 0;
+}
+
+sub IsPrimitiveType
+{
+ my $object = shift;
+ my $type = shift;
+
+ return 1 if $primitiveTypeHash{$type};
+ return 0;
+}
+
+sub IsStringType
+{
+ my $object = shift;
+ my $type = shift;
+
+ return 1 if $stringTypeHash{$type};
+ return 0;
+}
+
+sub IsNonPointerType
+{
+ my $object = shift;
+ my $type = shift;
+
+ return 1 if $nonPointerTypeHash{$type} or $primitiveTypeHash{$type};
+ return 0;
+}
+
+sub IsSVGAnimatedType
+{
+ my $object = shift;
+ my $type = shift;
+
+ return 1 if $svgAnimatedTypeHash{$type};
+ return 0;
+}
+
+# Internal Helper
+sub ScanDirectory
+{
+ my $object = shift;
+
+ my $interface = shift;
+ my $directory = shift;
+ my $useDirectory = shift;
+ my $reportAllFiles = shift;
+
+ print "Scanning interface " . $interface . " in " . $directory . "\n" if $verbose;
+
+ return if ($endCondition eq 1) and ($reportAllFiles eq 0);
+
+ my $sourceRoot = $ENV{SOURCE_ROOT};
+ my $thisDir = $sourceRoot ? "$sourceRoot/$directory" : $directory;
+
+ opendir(DIR, $thisDir) or die "[ERROR] Can't open directory $thisDir: \"$!\"\n";
+
+ my @names = readdir(DIR) or die "[ERROR] Cant't read directory $thisDir \"$!\"\n";
+ closedir(DIR);
+
+ foreach my $name (@names) {
+ # Skip if we already found the right file or
+ # if we encounter 'exotic' stuff (ie. '.', '..', '.svn')
+ next if ($endCondition eq 1) or ($name =~ /^\./);
+
+ # Recurisvely enter directory
+ if (-d "$thisDir/$name") {
+ $object->ScanDirectory($interface, "$directory/$name", $useDirectory, $reportAllFiles);
+ next;
+ }
+
+ # Check wheter we found the desired file
+ my $condition = ($name eq $interface);
+ $condition = 1 if ($interface eq "allidls") and ($name =~ /\.idl$/);
+
+ if ($condition) {
+ $foundFilename = "$thisDir/$name";
+
+ if ($reportAllFiles eq 0) {
+ $endCondition = 1;
+ } else {
+ push(@foundFilenames, $foundFilename);
+ }
+ }
+ }
+}
+
+1;
diff --git a/V8Binding/scripts/CodeGeneratorV8.pm b/V8Binding/scripts/CodeGeneratorV8.pm
new file mode 100644
index 0000000..95935b6
--- /dev/null
+++ b/V8Binding/scripts/CodeGeneratorV8.pm
@@ -0,0 +1,2181 @@
+
+# Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
+# Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
+# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+# Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
+# Copyright (C) 2006 Apple Computer, Inc.
+# Copyright (C) 2007 Google Inc.
+#
+# This file is part of the KDE project
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# aint with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+package CodeGeneratorV8;
+
+use File::stat;
+
+my $module = "";
+my $outputDir = "";
+
+my @headerContent = ();
+my @implContentHeader = ();
+my @implFixedHeader = ();
+my @implContent = ();
+my @implContentDecls = ();
+my %implIncludes = ();
+
+my @allParents = ();
+
+# Default .h template
+my $headerTemplate = << "EOF";
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+EOF
+
+# Default constructor
+sub new
+{
+ my $object = shift;
+ my $reference = { };
+
+ $codeGenerator = shift;
+ $outputDir = shift;
+
+ bless($reference, $object);
+ return $reference;
+}
+
+sub finish
+{
+ my $object = shift;
+
+ # Commit changes!
+ $object->WriteData();
+}
+
+sub leftShift($$) {
+ my ($value, $distance) = @_;
+ return (($value << $distance) & 0xFFFFFFFF);
+}
+
+# Uppercase the first letter, while respecting WebKit style guidelines.
+# E.g., xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang.
+sub WK_ucfirst
+{
+ my $param = shift;
+ my $ret = ucfirst($param);
+ $ret =~ s/Xml/XML/ if $ret =~ /^Xml[^a-z]/;
+ return $ret;
+}
+
+# Lowercase the first letter while respecting WebKit style guidelines.
+# URL becomes url, but SetURL becomes setURL.
+sub WK_lcfirst
+{
+ my $param = shift;
+ my $ret = lcfirst($param);
+ $ret =~ s/uRL/url/;
+ return $ret;
+}
+
+# Params: 'domClass' struct
+sub GenerateInterface
+{
+ my $object = shift;
+ my $dataNode = shift;
+ my $defines = shift;
+
+ # Start actual generation
+ $object->GenerateHeader($dataNode);
+ $object->GenerateImplementation($dataNode);
+
+ my $name = $dataNode->name;
+
+ # Open files for writing
+ my $headerFileName = "$outputDir/V8$name.h";
+ my $implFileName = "$outputDir/V8$name.cpp";
+
+ open($IMPL, ">$implFileName") || die "Couldn't open file $implFileName";
+ open($HEADER, ">$headerFileName") || die "Couldn't open file $headerFileName";
+}
+
+# Params: 'idlDocument' struct
+sub GenerateModule
+{
+ my $object = shift;
+ my $dataNode = shift;
+
+ $module = $dataNode->module;
+}
+
+sub GetLegacyHeaderIncludes
+{
+ my $legacyParent = shift;
+
+ die "Don't know what headers to include for module $module";
+}
+
+sub AvoidInclusionOfType
+{
+ my $type = shift;
+
+ # Special case: SVGRect.h / SVGPoint.h / SVGNumber.h / SVGMatrix.h do not exist.
+ return 1 if $type eq "SVGRect" or $type eq "SVGPoint" or $type eq "SVGNumber" or $type eq "SVGMatrix";
+ return 0;
+}
+
+sub UsesManualToJSImplementation
+{
+ my $type = shift;
+
+ return 1 if $type eq "SVGPathSeg";
+ return 0;
+}
+
+sub AddIncludesForType
+{
+ my $type = $codeGenerator->StripModule(shift);
+
+ # When we're finished with the one-file-per-class
+ # reorganization, we won't need these special cases.
+ if ($codeGenerator->IsPrimitiveType($type) or AvoidInclusionOfType($type)
+# jhaas: there doesn't seem to be any harm in leaving these in
+# or $type eq "DOMString" or $type eq "DOMObject" or $type eq "RGBColor" or $type eq "Rect") {
+ ) {
+ } elsif ($type =~ /SVGPathSeg/) {
+ $joinedName = $type;
+ $joinedName =~ s/Abs|Rel//;
+ $implIncludes{"${joinedName}.h"} = 1;
+ } else {
+ # default, include the same named file
+ $implIncludes{GetImplementationFileName(${type})} = 1;
+ }
+
+ # additional includes (things needed to compile the bindings but not the header)
+
+ if ($type eq "CanvasRenderingContext2D") {
+ $implIncludes{"CanvasGradient.h"} = 1;
+ $implIncludes{"CanvasPattern.h"} = 1;
+ $implIncludes{"CanvasStyle.h"} = 1;
+ }
+
+ if ($type eq "CanvasGradient" or $type eq "XPathNSResolver") {
+ $implIncludes{"PlatformString.h"} = 1;
+ }
+
+ if ($type eq "CSSStyleDeclaration") {
+ $implIncludes{"CSSMutableStyleDeclaration.h"} = 1;
+ }
+
+ if ($type eq "Plugin" or $type eq "PluginArray" or $type eq "MimeTypeArray") {
+ # So we can get String -> AtomicString conversion for namedItem().
+ $implIncludes{"AtomicString.h"} = 1;
+ }
+}
+
+sub AddIncludesForSVGAnimatedType
+{
+ my $type = shift;
+ $type =~ s/SVGAnimated//;
+
+ if ($type eq "Point" or $type eq "Rect") {
+ $implIncludes{"Float$type.h"} = 1;
+ } elsif ($type eq "String") {
+ $implIncludes{"PlatformString.h"} = 1;
+ }
+
+ $implIncludes{"SVGAnimatedTemplate.h"} = 1;
+}
+
+sub AddClassForwardIfNeeded
+{
+ my $implClassName = shift;
+
+ # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
+ push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
+}
+
+sub GetImplementationFileName
+{
+ my $iface = shift;
+ return "HTMLCollection.h" if $iface eq "UndetectableHTMLCollection";
+ return "Event.h" if $iface eq "DOMTimeStamp";
+ return "NamedAttrMap.h" if $iface eq "NamedNodeMap";
+ return "NameNodeList.h" if $iface eq "NodeList";
+ return "XMLHttpRequest.h" if $iface eq "XMLHttpRequest";
+
+ return "${iface}.h";
+}
+
+sub GenerateHeader
+{
+ my $object = shift;
+ my $dataNode = shift;
+
+ my $interfaceName = $dataNode->name;
+ my $className = "V8$interfaceName";
+ my $implClassName = $interfaceName;
+
+ # Copy contents of parent classes except the first parent or if it is
+ # EventTarget.
+ $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode);
+
+ my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
+ my $conditional = $dataNode->extendedAttributes->{"Conditional"};
+
+ # - Add default header template
+ @headerContent = split("\r", $headerTemplate);
+
+ # - Add header protection
+ if ($className =~ /^V8SVG/) {
+ push(@headerContent, "\n#if ENABLE(SVG)\n");
+ } elsif (IsVideoClassName($className)) {
+ push(@headerContent, "\n#if ENABLE(VIDEO)\n");
+ } elsif (IsWorkerClassName($className)) {
+ push(@headerContent, "\n#if ENABLE(WORKERS)\n");
+ }
+
+ push(@headerContent, "\n#ifndef $className" . "_H");
+ push(@headerContent, "\n#define $className" . "_H\n\n");
+
+ # Get correct pass/store types respecting PODType flag
+ my $podType = $dataNode->extendedAttributes->{"PODType"};
+ my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName*";
+
+ push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
+
+ push(@headerContent, "#include <v8.h>\n");
+ push(@headerContent, "#include <wtf/HashMap.h>\n");
+ push(@headerContent, "#include \"StringHash.h\"\n");
+
+ push(@headerContent, "\nnamespace WebCore {\n\n");
+ push(@headerContent, "class V8ClassIndex;\n");
+ push(@headerContent, "\nclass $className {\n");
+ push(@headerContent, <<END);
+
+ public:
+ static bool HasInstance(v8::Handle<v8::Value> value);
+ static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
+END
+
+ if ($implClassName eq "DOMWindow") {
+ push(@headerContent, <<END);
+ static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
+END
+ }
+
+ push(@headerContent, <<END);
+
+ private:
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+
+ friend class V8ClassIndex;
+};
+
+END
+
+ push(@headerContent, "}\n\n");
+ push(@headerContent, "#endif // $className" . "_H\n");
+
+ if ($className =~ /^V8SVG/) {
+ push(@headerContent, "\n#endif // ENABLE(SVG)\n");
+ } elsif (IsVideoClassName($className)) {
+ push(@headerContent, "\n#endif // ENABLE(VIDEO)\n");
+ } elsif (IsWorkerClassName($className)) {
+ push(@headerContent, "\n#endif // ENABLE(WORKERS)\n");
+ }
+}
+
+
+sub GenerateSetDOMException
+{
+ my $indent = shift;
+ my $result = "";
+
+ $result .= $indent . "if (ec) {\n";
+ $result .= $indent . " V8Proxy::SetDOMException(ec);\n";
+ $result .= $indent . " return v8::Handle<v8::Value>();\n";
+ $result .= $indent . "}\n";
+
+ return $result;
+}
+
+sub IsNodeSubType
+{
+ my $dataNode = shift;
+ return 1 if ($dataNode->name eq "Node");
+ foreach (@allParents) {
+ my $parent = $codeGenerator->StripModule($_);
+ return 1 if $parent eq "Node";
+ }
+ return 0;
+}
+
+sub HolderToNative
+{
+ my $dataNode = shift;
+ my $implClassName = shift;
+ my $classIndex = shift;
+
+ if (IsNodeSubType($dataNode)) {
+ push(@implContentDecls, <<END);
+ $implClassName* imp = V8Proxy::DOMWrapperToNode<$implClassName>(holder);
+END
+
+ } else {
+ push(@implContentDecls, <<END);
+ $implClassName* imp = V8Proxy::ToNativeObject<$implClassName>(V8ClassIndex::$classIndex, holder);
+END
+
+ }
+}
+
+sub GenerateDomainSafeFunctionGetter
+{
+ my $function = shift;
+ my $dataNode = shift;
+ my $classIndex = shift;
+ my $implClassName = shift;
+
+ my $className = "V8" . $dataNode->name;
+ my $funcName = $function->signature->name;
+
+ my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())";
+ if ($function->signature->extendedAttributes->{"V8DoNotCheckSignature"}) {
+ $signature = "v8::Local<v8::Signature>()";
+ }
+
+ my $newTemplateString = GenerateNewFunctionTemplate($function, $dataNode, $signature);
+
+ $implIncludes{"v8_proxy.h"} = 1;
+
+ push(@implContentDecls, <<END);
+ static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+ INC_STATS(\"DOM.$implClassName.$funcName._get\");
+ static v8::Persistent<v8::FunctionTemplate> private_template =
+ v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
+ if (holder.IsEmpty()) {
+ // can only reach here by 'object.__proto__.func', and it should passed
+ // domain security check already
+
+ return private_template->GetFunction();
+ }
+END
+
+ HolderToNative($dataNode, $implClassName, $classIndex);
+
+ push(@implContentDecls, <<END);
+ if (!V8Proxy::CanAccessFrame(imp->frame(), false)) {
+ static v8::Persistent<v8::FunctionTemplate> shared_template =
+ v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ return shared_template->GetFunction();
+
+ } else {
+ return private_template->GetFunction();
+ }
+ }
+
+END
+}
+
+sub GenerateConstructorGetter
+{
+ my $implClassName = shift;
+ my $classIndex = shift;
+
+ push(@implContentDecls, <<END);
+ static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+ INC_STATS(\"DOM.$implClassName.constructors._get\");
+ v8::Handle<v8::Value> data = info.Data();
+ ASSERT(data->IsNumber());
+ V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value());
+END
+
+ if ($classIndex eq "DOMWINDOW") {
+ push(@implContentDecls, <<END);
+ DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
+ Frame* frame = window->frame();
+ if (frame) {
+ // Get the proxy corresponding to the DOMWindow if possible to
+ // make sure that the constructor function is constructed in the
+ // context of the DOMWindow and not in the context of the caller.
+ return V8Proxy::retrieve(frame)->GetConstructor(type);
+ }
+END
+ }
+
+ if ($classIndex eq "WORKERCONTEXT") {
+ $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
+ push(@implContentDecls, <<END);
+ return WorkerContextExecutionProxy::retrieve()->GetConstructor(type);
+END
+ } else {
+ push(@implContentDecls, " return V8Proxy::retrieve()->GetConstructor(type);");
+ }
+
+ push(@implContentDecls, <<END);
+ }
+
+END
+}
+
+sub GenerateNormalAttrGetter
+{
+ my $attribute = shift;
+ my $dataNode = shift;
+ my $classIndex = shift;
+ my $implClassName = shift;
+
+ my $attrExt = $attribute->signature->extendedAttributes;
+
+ my $attrName = $attribute->signature->name;
+ $implIncludes{"v8_proxy.h"} = 1;
+
+ my $attrType = $codeGenerator->StripModule($attribute->signature->type);
+ my $attrIsPodType = $codeGenerator->IsPodType($attrType);
+ my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
+ my $isPodType = $codeGenerator->IsPodType($implClassName);
+ my $skipContext = 0;
+
+
+ if ($isPodType) {
+ $implClassName = GetNativeType($implClassName);
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+ }
+
+ # Special case: SVGZoomEvent's attributes are all read-only
+ if ($implClassName eq "SVGZoomEvent") {
+ $attrIsPodType = 0;
+ $skipContext = 1;
+ }
+
+ # Special case: SVGSVGEelement::viewport is read-only
+ if (($implClassName eq "SVGSVGElement") and ($attrName eq "viewport")) {
+ $attrIsPodType = 0;
+ $skipContext = 1;
+ }
+
+ # Special case for SVGColor
+ if (($implClassName eq "SVGColor") and ($attrName eq "rgbColor")) {
+ $attrIsPodType = 0;
+ }
+
+ my $getterStringUsesImp = $implClassName ne "double";
+
+ # Getter
+ push(@implContentDecls, <<END);
+ static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+ INC_STATS(\"DOM.$implClassName.$attrName._get\");
+END
+
+ if ($isPodType) {
+ push(@implContentDecls, <<END);
+ V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());
+ $implClassName imp_instance = *imp_wrapper;
+END
+ if ($getterStringUsesImp) {
+ push(@implContentDecls, <<END);
+ $implClassName* imp = &imp_instance;
+END
+ }
+
+ } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
+ # perform lookup first
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
+ if (holder.IsEmpty()) return v8::Undefined();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ } else {
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = info.Holder();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ }
+
+ # Generate security checks if necessary
+ if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
+ push(@implContentDecls, " if (!V8Proxy::CheckNodeSecurity(imp->$attrName())) return v8::Undefined();\n\n");
+ } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
+ push(@implContentDecls, " if (!V8Proxy::CheckNodeSecurity(imp->contentDocument())) return v8::Undefined();\n\n");
+ }
+
+ my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
+ if ($useExceptions) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls, " ExceptionCode ec = 0;\n");
+ }
+
+ if ($attribute->signature->extendedAttributes->{"v8referenceattr"}) {
+ $attrName = $attribute->signature->extendedAttributes->{"v8referenceattr"};
+ }
+
+ my $getterFunc = WK_lcfirst($attrName);
+ $getterFunc .= "Animated" if $codeGenerator->IsSVGAnimatedType($attribute->signature->type);
+
+ my $returnType = $codeGenerator->StripModule($attribute->signature->type);
+
+ my $getterString;
+ if ($getterStringUsesImp) {
+ $getterString = "imp->$getterFunc(";
+ $getterString .= "ec" if $useExceptions;
+ $getterString .= ")";
+ if (IsRefPtrType($returnType)) {
+ $implIncludes{"wtf/GetPtr.h"} = 1;
+ $getterString = "WTF::getPtr(" . $getterString . ")";
+ }
+ if ($nativeType eq "int" and
+ $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ $getterString .= ".toInt()";
+ }
+ } else {
+ $getterString = "imp_instance";
+ }
+ if ($nativeType eq "String") {
+ $getterString = "ToString($getterString)";
+ }
+
+ my $result;
+ my $wrapper;
+
+ if ($attrIsPodType) {
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+
+ my $getter = $getterString;
+ $getter =~ s/imp->//;
+ $getter =~ s/\(\)//;
+ my $setter = "set" . WK_ucfirst($getter);
+
+ my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassName);
+ if (not $implClassIsAnimatedType
+ and $codeGenerator->IsPodTypeWithWriteableProperties($attrType)
+ and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
+ if ($codeGenerator->IsPodType($implClassName)) {
+ $wrapper = "new V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>($getterString, imp_wrapper)";
+ } else {
+ $wrapper = "new V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
+ }
+ } else {
+ if ($implClassIsAnimatedType) {
+ $wrapper = "V8SVGDynamicPODTypeWrapperCache<$nativeType, $implClassName>::lookupOrCreateWrapper(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
+ } else {
+ $wrapper = GenerateSVGStaticPodTypeWrapper($returnType, $getterString);
+ }
+ }
+
+ push(@implContentDecls, " void* wrapper = $wrapper;\n");
+ } elsif ($nativeType ne "RGBColor") {
+ push(@implContentDecls, " $nativeType v = ");
+
+ push(@implContentDecls, "$getterString;\n");
+
+ if ($useExceptions) {
+ push(@implContentDecls, GenerateSetDOMException(" "));
+ }
+
+ $result = "v";
+ if (IsRefPtrType($returnType)) {
+ $result = "WTF::getPtr(" . $result . ")";
+ }
+ } else {
+ # Special case: RGBColor is noncopyable
+ $result = $getterString;
+ }
+
+
+ if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
+ my $resultObject = $result;
+ if ($attrIsPodType) {
+ $resultObject = "wrapper";
+ }
+
+ push(@implContentDecls, GenerateSVGContextAssignment($implClassName, $resultObject, " "));
+ }
+
+ if ($attrIsPodType) {
+ my $classIndex = uc($attrType);
+ push(@implContentDecls, " return V8Proxy::ToV8Object(V8ClassIndex::$classIndex, wrapper);\n");
+ } else {
+ push(@implContentDecls, " return " . NativeToJSValue($attribute->signature, $result). ";\n");
+ }
+
+ push(@implContentDecls, " }\n\n"); # end of getter
+}
+
+
+sub GenerateReplaceableAttrSetter
+{
+ my $implClassName = shift;
+
+ $implIncludes{"v8_proxy.h"} = 1;
+
+ push(@implContentDecls,
+ " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
+ " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
+
+ push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
+
+ push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n");
+ push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n");
+ push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n");
+ push(@implContentDecls, " }\n\n");
+}
+
+
+sub GenerateNormalAttrSetter
+{
+ my $attribute = shift;
+ my $dataNode = shift;
+ my $classIndex = shift;
+ my $implClassName = shift;
+
+ my $attrExt = $attribute->signature->extendedAttributes;
+
+ $implIncludes{"v8_proxy.h"} = 1;
+
+ push(@implContentDecls,
+ " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
+ " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
+
+ push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
+
+ my $isPodType = $codeGenerator->IsPodType($implClassName);
+
+ if ($isPodType) {
+ $implClassName = GetNativeType($implClassName);
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+ push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n");
+ push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n");
+ push(@implContentDecls, " $implClassName* imp = &imp_instance;\n");
+
+ } elsif ($attrExt->{"v8OnProto"}) {
+ # perform lookup first
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
+ if (holder.IsEmpty()) return v8::Undefined();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ } else {
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = info.Holder();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ }
+
+ my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
+ push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
+
+ my $result = "";
+ if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ $result .= "WebCore::String::number(";
+ }
+ $result .= "v";
+ if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ $result .= ")";
+ }
+ my $returnType = $codeGenerator->StripModule($attribute->signature->type);
+ if (IsRefPtrType($returnType)) {
+ $result = "WTF::getPtr(" . $result . ")";
+ }
+
+ my $useExceptions = 1 if @{$attribute->setterExceptions} and !($isPodType);
+
+ if ($useExceptions) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls, " ExceptionCode ec = 0;\n");
+ }
+
+ if ($implClassName eq "double") {
+ push(@implContentDecls, " *imp = $result;\n");
+ } else {
+ push(@implContentDecls, " imp->set" . WK_ucfirst($attrName) . "(" . $result);
+ push(@implContentDecls, ", ec") if $useExceptions;
+ push(@implContentDecls, ");\n");
+ }
+
+ if ($useExceptions) {
+ push(@implContentDecls, " V8Proxy::SetDOMException(ec);\n");
+ }
+
+ if ($isPodType) {
+ push(@implContentDecls, " wrapper->commitChange(*imp, V8Proxy::GetSVGContext(wrapper));\n");
+ } elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
+ $implIncludes{"SVGElement.h"} = 1;
+
+ my $currentObject = "imp";
+ if ($isPodType) {
+ $currentObject = "wrapper";
+ }
+
+ push(@implContentDecls, " if (SVGElement* context = V8Proxy::GetSVGContext($currentObject)) {\n");
+ push(@implContentDecls, " context->svgAttributeChanged(imp->associatedAttributeName());\n");
+ push(@implContentDecls, " }\n");
+ }
+
+ push(@implContentDecls, " return;\n");
+ push(@implContentDecls, " }\n\n"); # end of setter
+}
+
+
+sub GenerateNewFunctionTemplate
+{
+ $function = shift;
+ $dataNode = shift;
+ $signature = shift;
+
+ my $interfaceName = $dataNode->name;
+ my $name = $function->signature->name;
+
+ if ($function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"V8Custom"}) {
+ if ($function->signature->extendedAttributes->{"Custom"} &&
+ $function->signature->extendedAttributes->{"V8Custom"}) {
+ die "Custom and V8Custom should be mutually exclusive!"
+ }
+ my $customFunc = $function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"V8Custom"};
+ if ($customFunc eq 1) {
+ $customFunc = $interfaceName . WK_ucfirst($name);
+ }
+ return "v8::FunctionTemplate::New(V8Custom::v8${customFunc}Callback, v8::Handle<v8::Value>(), $signature)";
+ } else {
+ return "v8::FunctionTemplate::New(${interfaceName}Internal::${name}Callback, v8::Handle<v8::Value>(), $signature)";
+ }
+}
+
+
+sub GenerateFunctionCallback
+{
+ my $function = shift;
+ my $dataNode = shift;
+ my $classIndex = shift;
+ my $implClassName = shift;
+
+ my $interfaceName = $dataNode->name;
+ my $name = $function->signature->name;
+
+ push(@implContentDecls,
+" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
+" INC_STATS(\"DOM.$implClassName.$name\");\n");
+
+ my $numParameters = @{$function->parameters};
+
+ if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
+ push(@implContentDecls,
+ " if (args.Length() < $numParameters) return v8::Undefined();\n");
+ }
+
+ if ($codeGenerator->IsPodType($implClassName)) {
+ my $nativeClassName = GetNativeType($implClassName);
+ push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n");
+ push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n");
+ push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n");
+ } else {
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Value> holder = args.Holder();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ }
+
+ # Check domain security if needed
+ if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
+ || $interfaceName eq "DOMWindow")
+ && !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
+ # We have not find real use cases yet.
+ push(@implContentDecls,
+" if (!V8Proxy::CanAccessFrame(imp->frame(), true)) {\n".
+" return v8::Undefined();\n" .
+" }\n");
+ }
+
+
+ if (@{$function->raisesExceptions}) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls, " ExceptionCode ec = 0;\n");
+ }
+
+ if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
+ push(@implContentDecls, " ScriptCallStack callStack(args, $numParameters);\n");
+ $implIncludes{"ScriptCallStack.h"} = 1;
+ }
+
+ my $paramIndex = 0;
+ foreach my $parameter (@{$function->parameters}) {
+ TranslateParameter($parameter);
+
+ my $parameterName = $parameter->name;
+
+ if ($parameter->extendedAttributes->{"Optional"}) {
+ # Generate early call if there are not enough parameters.
+ push(@implContentDecls, " if (args.Length() <= $paramIndex) {\n");
+ my $functionCall = GenerateFunctionCallString($function, $paramIndex, " " x 2, $implClassName);
+ push(@implContentDecls, $functionCall);
+ push(@implContentDecls, " }\n");
+ }
+
+ if (BasicTypeCanFailConversion($parameter)) {
+ push(@implContentDecls, " bool ${parameterName}Ok;\n");
+ }
+
+ push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, 1) . " $parameterName = ");
+ push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
+ BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
+
+ if (TypeCanFailConversion($parameter)) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls,
+" if (!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ") {\n" .
+" V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);\n" .
+" return v8::Handle<v8::Value>();\n" .
+" }\n");
+ }
+
+ if ($parameter->extendedAttributes->{"IsIndex"}) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls,
+" if ($parameterName < 0) {\n" .
+" V8Proxy::SetDOMException(INDEX_SIZE_ERR);\n" .
+" return v8::Handle<v8::Value>();\n" .
+" }\n");
+ }
+
+ $paramIndex++;
+ }
+
+ # Build the function call string.
+ my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName);
+ push(@implContentDecls, "$callString");
+ push(@implContentDecls, " }\n\n");
+}
+
+
+sub GenerateBatchedAttributeData
+{
+ my $interfaceName = shift;
+ my $attributes = shift;
+
+ foreach my $attribute (@$attributes) {
+ my $attrName = $attribute->signature->name;
+ my $attrExt = $attribute->signature->extendedAttributes;
+
+ my $accessControl = "v8::DEFAULT";
+ if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {
+ $accessControl = "v8::ALL_CAN_READ";
+ } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) {
+ $accessControl = "v8::ALL_CAN_WRITE";
+ } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
+ $accessControl = "v8::ALL_CAN_READ";
+ if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
+ $accessControl .= "|v8::ALL_CAN_WRITE";
+ }
+ }
+ if ($attrExt->{"V8DisallowShadowing"}) {
+ $accessControl .= "|v8::PROHIBITS_OVERWRITING";
+ }
+ $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
+
+
+ my $customAccessor =
+ $attrExt->{"Custom"} ||
+ $attrExt->{"CustomSetter"} ||
+ $attrExt->{"CustomGetter"} ||
+ $attrExt->{"V8Custom"} ||
+ $attrExt->{"V8CustomSetter"} ||
+ $attrExt->{"V8CustomGetter"} ||
+ "";
+ if ($customAccessor eq 1) {
+ # use the naming convension, interface + (capitalize) attr name
+ $customAccessor = $interfaceName . WK_ucfirst($attrName);
+ }
+
+ my $getter;
+ my $setter;
+ my $propAttr = "v8::None";
+
+ # Check attributes.
+ if ($attrExt->{"DontEnum"}) {
+ $propAttr .= "|v8::DontEnum";
+ }
+ if ($attrExt->{"V8DisallowShadowing"}) {
+ $propAttr .= "|v8::DontDelete";
+ }
+
+ my $on_proto = "0 /* on instance */";
+ my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
+
+ # Constructor
+ if ($attribute->signature->type =~ /Constructor$/) {
+ my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
+ $constructorType =~ s/Constructor$//;
+ my $constructorIndex = uc($constructorType);
+ $data = "V8ClassIndex::${constructorIndex}";
+ $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
+ $setter = "0";
+ $propAttr = "v8::ReadOnly";
+
+ # EventListeners
+ } elsif ($attrExt->{"ProtectedListener"}) {
+ if ($interfaceName eq "DOMWindow") {
+ $getter = "V8Custom::v8DOMWindowEventHandlerAccessorGetter";
+ $setter = "V8Custom::v8DOMWindowEventHandlerAccessorSetter";
+ } else {
+ $getter = "V8Custom::v8ElementEventHandlerAccessorGetter";
+ $setter = "V8Custom::v8ElementEventHandlerAccessorSetter";
+ }
+
+ # Custom Getter and Setter
+ } elsif ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
+ $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
+ $setter = "0";
+ $propAttr = "v8::ReadOnly";
+ } else {
+ $setter = "V8Custom::v8${customAccessor}AccessorSetter";
+ }
+
+ # Custom Setter
+ } elsif ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"}) {
+ $getter = "${interfaceName}Internal::${attrName}AttrGetter";
+ $setter = "V8Custom::v8${customAccessor}AccessorSetter";
+
+ # Custom Getter
+ } elsif ($attrExt->{"CustomGetter"}) {
+ $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ $setter = "${interfaceName}Internal::${attrName}AttrSetter";
+
+ # Replaceable
+ } elsif ($attrExt->{"Replaceable"}) {
+ # Replaceable accessor is put on instance template with ReadOnly attribute.
+ $getter = "${interfaceName}Internal::${attrName}AttrGetter";
+ $setter = "0";
+ $propAttr .= "|v8::ReadOnly";
+
+ # Normal
+ } else {
+ $getter = "${interfaceName}Internal::${attrName}AttrGetter";
+ $setter = "${interfaceName}Internal::${attrName}AttrSetter";
+ }
+
+ # Read only attributes
+ if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {
+ $setter = "0";
+ }
+
+ # An accessor can be installed on the proto
+ if ($attrExt->{"v8OnProto"}) {
+ $on_proto = "1 /* on proto */";
+ }
+
+ my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
+ "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
+ push(@implContent, <<END);
+ // $commentInfo
+ { "$attrName",
+ $getter,
+ $setter,
+ $data,
+ $accessControl,
+ static_cast<v8::PropertyAttribute>($propAttr),
+ $on_proto },
+END
+ }
+}
+
+
+sub GenerateImplementation
+{
+ my $object = shift;
+ my $dataNode = shift;
+ my $interfaceName = $dataNode->name;
+ my $className = "V8$interfaceName";
+ my $implClassName = $interfaceName;
+ my $classIndex = uc($codeGenerator->StripModule($interfaceName));
+
+ my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
+ my $conditional = $dataNode->extendedAttributes->{"Conditional"};
+
+ @allParents = $codeGenerator->FindParentsRecursively($dataNode);
+
+ # - Add default header template
+ @implContentHeader = split("\r", $headerTemplate);
+
+ push(@implFixedHeader,
+ "#include \"config.h\"\n" .
+ "#include \"v8_proxy.h\"\n" .
+ "#include \"v8_binding.h\"\n\n" .
+ "#undef LOG\n\n");
+
+ if ($className =~ /^V8SVG/) {
+ push(@implFixedHeader, "#if ENABLE(SVG)\n\n");
+ } elsif (IsVideoClassName($className)) {
+ push(@implFixedHeader, "#if ENABLE(VIDEO)\n\n");
+ } elsif (IsWorkerClassName($className)) {
+ push(@implFixedHeader, "#if ENABLE(WORKERS)\n\n");
+ }
+
+ if ($className =~ /^V8SVGAnimated/) {
+ AddIncludesForSVGAnimatedType($interfaceName);
+ }
+
+ $implIncludes{"${className}.h"} = 1;
+
+ AddIncludesForType($interfaceName);
+ $implIncludes{"v8_proxy.h"} = 1;
+
+ push(@implContentDecls, "namespace WebCore {\n");
+ push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
+ push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
+
+ my $hasConstructors = 0;
+
+ # Generate property accessors for attributes.
+ for ($index = 0; $index < @{$dataNode->attributes}; $index++) {
+ $attribute = @{$dataNode->attributes}[$index];
+ $attrName = $attribute->signature->name;
+ $attrType = $attribute->signature->type;
+
+ # Generate special code for the constructor attributes.
+ if ($attrType =~ /Constructor$/) {
+ $hasConstructors = 1;
+ next;
+ }
+
+ # Make EventListeners always custom.
+ # TODO(mbelshe): make the perl code capable of generating the
+ # event setters/getters. For now, WebKit has started removing the
+ # [Custom] attribute, so just automatically insert it to avoid forking
+ # other files. This should be okay because we can't generate stubs
+ # for any event getter/setters anyway.
+ if ($attrType eq "EventListener") {
+ $attribute->signature->extendedAttributes->{"Custom"} = 1;
+ $implIncludes{"v8_custom.h"} = 1;
+ next;
+ }
+
+ # Do not generate accessor if this is a custom attribute. The
+ # call will be forwarded to a hand-written accessor
+ # implementation.
+ if ($attribute->signature->extendedAttributes->{"Custom"} ||
+ $attribute->signature->extendedAttributes->{"V8Custom"}) {
+ $implIncludes{"v8_custom.h"} = 1;
+ next;
+ }
+
+ # Generate the accessor.
+ if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
+ $implIncludes{"v8_custom.h"} = 1;
+ } else {
+ GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName);
+ }
+ if ($attribute->signature->extendedAttributes->{"CustomSetter"} ||
+ $attribute->signature->extendedAttributes->{"V8CustomSetter"}) {
+ $implIncludes{"v8_custom.h"} = 1;
+ } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
+ $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!";
+# GenerateReplaceableAttrSetter($implClassName);
+ } elsif ($attribute->type !~ /^readonly/ &&
+ !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
+ GenerateNormalAttrSetter($attribute, $dataNode, $classIndex, $implClassName);
+ }
+ }
+
+ if ($hasConstructors) {
+ GenerateConstructorGetter($implClassName, $classIndex);
+ }
+
+ # Generate methods for functions.
+ foreach my $function (@{$dataNode->functions}) {
+ # hack for addEventListener/RemoveEventListener
+ # TODO(fqian): avoid naming conflict
+ if ($function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"V8Custom"}) {
+ $implIncludes{"v8_custom.h"} = 1;
+
+ } else {
+ GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName);
+ }
+
+
+ # If the function does not need domain security check, we need to
+ # generate an access getter that returns different function objects
+ # for different calling context.
+ if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
+ || ($interfaceName eq "DOMWindow"))
+ && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}){
+ GenerateDomainSafeFunctionGetter($function, $dataNode, $classIndex, $implClassName);
+ }
+ }
+
+ # Attributes
+ my $attributes = $dataNode->attributes;
+
+ # For the DOMWindow interface we partition the attributes into the
+ # ones that disallows shadowing and the rest.
+ my @disallows_shadowing;
+ my @normal;
+ if ($interfaceName eq "DOMWindow") {
+ foreach my $attribute (@$attributes) {
+ if ($attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
+ push(@disallows_shadowing, $attribute);
+ } else {
+ push(@normal, $attribute);
+ }
+ }
+ # Put the attributes that disallow shadowing on the shadow object.
+ $attributes = \@normal;
+ push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n");
+ GenerateBatchedAttributeData($interfaceName, \@disallows_shadowing);
+ push(@implContent, "};\n");
+
+ }
+
+ my $has_attributes = 0;
+ if (@$attributes) {
+ $has_attributes = 1;
+ push(@implContent, "static const BatchedAttribute attrs[] = {\n");
+ GenerateBatchedAttributeData($interfaceName, $attributes);
+ push(@implContent, "};\n");
+ }
+
+ # Setup constants
+ my $has_constants = 0;
+ if (@{$dataNode->constants}) {
+ $has_constants = 1;
+ push(@implContent, "static const BatchedConstant consts[] = {\n");
+ }
+ foreach my $constant (@{$dataNode->constants}) {
+ my $name = $constant->name;
+ my $value = $constant->value;
+ # TODO we need the static_cast here only because of one constant, NodeFilter.idl
+ # defines "const unsigned long SHOW_ALL = 0xFFFFFFFF". It would be better if we
+ # handled this here, and converted it to a -1 constant in the c++ output.
+ push(@implContent, <<END);
+ { "${name}", static_cast<signed int>($value) },
+END
+ }
+ if ($has_constants) {
+ push(@implContent, "};\n");
+ }
+
+ push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
+
+ my $access_check = "/* no access check */";
+ if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} &&
+ !($interfaceName eq "DOMWindow")) {
+ $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));";
+ }
+
+ # For the DOMWindow interface, generate the shadow object template
+ # configuration method.
+ if ($implClassName eq "DOMWindow") {
+ push(@implContent, <<END);
+static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) {
+ BatchConfigureAttributes(templ,
+ v8::Handle<v8::ObjectTemplate>(),
+ shadow_attrs,
+ sizeof(shadow_attrs)/sizeof(*shadow_attrs));
+ return templ;
+}
+END
+ }
+
+ # Generate the template configuration method
+ push(@implContent, <<END);
+static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ instance->SetInternalFieldCount(2);
+ v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
+ v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
+ $access_check
+END
+
+
+ # Set up our attributes if we have them
+ if ($has_attributes) {
+ push(@implContent, <<END);
+ BatchConfigureAttributes(instance, proto, attrs, sizeof(attrs)/sizeof(*attrs));
+END
+ }
+
+ # Define our functions with Set() or SetAccessor()
+ foreach my $function (@{$dataNode->functions}) {
+ my $attrExt = $function->signature->extendedAttributes;
+ my $name = $function->signature->name;
+
+ my $property_attributes = "v8::DontDelete";
+ if ($attrExt->{"DontEnum"}) {
+ $property_attributes .= "|v8::DontEnum";
+ }
+ if ($attrExt->{"V8ReadOnly"}) {
+ $property_attributes .= "|v8::ReadOnly";
+ }
+
+ my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
+
+ my $template = "proto";
+ if ($attrExt->{"V8OnInstance"}) {
+ $template = "instance";
+ }
+
+ if ($attrExt->{"DoNotCheckDomainSecurity"} &&
+ ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
+ # Mark the accessor as ReadOnly and set it on the proto object so
+ # it can be shadowed. This is really a hack to make it work.
+ # There are several sceneria to call into the accessor:
+ # 1) from the same domain: "window.open":
+ # the accessor finds the DOM wrapper in the proto chain;
+ # 2) from the same domain: "window.__proto__.open":
+ # the accessor will NOT find a DOM wrapper in the prototype chain
+ # 3) from another domain: "window.open":
+ # the access find the DOM wrapper in the prototype chain
+ # "window.__proto__.open" from another domain will fail when
+ # accessing '__proto__'
+ #
+ # The solution is very hacky and fragile, it really needs to be replaced
+ # by a better solution.
+ $property_attributes .= "|v8::ReadOnly";
+ push(@implContent, <<END);
+
+ // $commentInfo
+ $template->SetAccessor(
+ v8::String::New("$name"),
+ ${interfaceName}Internal::${name}AttrGetter,
+ 0,
+ v8::Handle<v8::Value>(),
+ v8::ALL_CAN_READ,
+ static_cast<v8::PropertyAttribute>($property_attributes));
+END
+ next;
+ }
+
+ my $signature = "default_signature";
+ if ($attrExt->{"V8DoNotCheckSignature"}){
+ $signature = "v8::Local<v8::Signature>()";
+ }
+
+ if (RequiresCustomSignature($function)) {
+ $signature = "${name}_signature";
+ push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
+ }
+
+ # Normal function call is a template
+ my $templateFunction = GenerateNewFunctionTemplate($function, $dataNode, $signature);
+
+
+ push(@implContent, <<END);
+
+ // $commentInfo
+ ${template}->Set(
+ v8::String::New("$name"),
+ $templateFunction,
+ static_cast<v8::PropertyAttribute>($property_attributes));
+END
+ }
+
+ # set the super descriptor
+ foreach (@{$dataNode->parents}) {
+ my $parent = $codeGenerator->StripModule($_);
+ if ($parent eq "EventTarget") { next; }
+ $implIncludes{"V8${parent}.h"} = 1;
+ my $parentClassIndex = uc($codeGenerator->StripModule($parent));
+ push(@implContent, " desc->Inherit(V8Proxy::GetTemplate(V8ClassIndex::${parentClassIndex}));\n");
+ last;
+ }
+
+ # Set the class name. This is used when printing objects.
+ push(@implContent, " desc->SetClassName(v8::String::New(\"" . GetClassName(${interfaceName}) . "\"));\n");
+
+ if ($has_constants) {
+ push(@implContent, <<END);
+ BatchConfigureConstants(desc, proto, consts, sizeof(consts)/sizeof(*consts));
+END
+ }
+
+ push(@implContent, <<END);
+ return desc;
+}
+
+v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
+ static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_;
+ if (${className}_raw_cache_.IsEmpty()) {
+ v8::HandleScope scope;
+ v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::CheckNewLegal);
+ ${className}_raw_cache_ = v8::Persistent<v8::FunctionTemplate>::New(result);
+ }
+ return ${className}_raw_cache_;
+}
+
+v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
+ static v8::Persistent<v8::FunctionTemplate> ${className}_cache_;
+ if (${className}_cache_.IsEmpty())
+ ${className}_cache_ = Configure${className}Template(GetRawTemplate());
+ return ${className}_cache_;
+}
+
+bool ${className}::HasInstance(v8::Handle<v8::Value> value) {
+ return GetRawTemplate()->HasInstance(value);
+}
+
+END
+
+ if ($implClassName eq "DOMWindow") {
+ push(@implContent, <<END);
+v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() {
+ static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
+ if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
+ V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
+ ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
+ }
+ return V8DOMWindowShadowObject_cache_;
+}
+END
+ }
+
+ push(@implContent, <<END);
+} // namespace WebCore
+END
+
+ if ($className =~ /^V8SVG/) {
+ push(@implContent, "\n#endif // ENABLE(SVG)\n");
+ } elsif (IsVideoClassName($className)) {
+ push(@implContent, "\n#endif // ENABLE(VIDEO)\n");
+ } elsif (IsWorkerClassName($className)) {
+ push(@implContent, "\n#endif // ENABLE(WORKERS)\n");
+ }
+}
+
+
+sub GenerateFunctionCallString()
+{
+ my $function = shift;
+ my $numberOfParameters = shift;
+ my $indent = shift;
+ my $implClassName = shift;
+
+ my $name = $function->signature->name;
+ my $isPodType = $codeGenerator->IsPodType($implClassName);
+ my $returnType = $codeGenerator->StripModule($function->signature->type);
+ my $returnsPodType = $codeGenerator->IsPodType($returnType);
+ my $nativeReturnType = GetNativeType($returnType, 0);
+ my $result = "";
+
+ # Special case: SVG matrix transform methods should not mutate
+ # the matrix but return a copy
+ my $copyFirst = 0;
+ if ($implClassName eq "SVGMatrix" && $function->signature->type eq "SVGMatrix") {
+ $copyFirst = 1;
+ }
+
+ if ($function->signature->extendedAttributes->{"v8implname"}) {
+ $name = $function->signature->extendedAttributes->{"v8implname"};
+ }
+
+ if ($function->signature->extendedAttributes->{"ImplementationFunction"}) {
+ $name = $function->signature->extendedAttributes->{"ImplementationFunction"};
+ }
+
+ my $functionString = "imp->${name}(";
+
+ if ($copyFirst) {
+ $functionString = "result.${name}(";
+ }
+
+ my $returnsListItemPodType = 0;
+ # SVG lists functions that return POD types require special handling
+ if (IsSVGListTypeNeedingSpecialHandling($implClassName) && IsSVGListMethod($name) && $returnsPodType) {
+ $returnsListItemPodType = 1;
+ $result .= $indent . "SVGList<RefPtr<SVGPODListItem<$nativeReturnType> > >* listImp = imp;\n";
+ $functionString = "listImp->${name}(";
+ }
+
+ my $first = 1;
+ my $index = 0;
+ my $nodeToReturn = 0;
+
+ foreach my $parameter (@{$function->parameters}) {
+ if ($index eq $numberOfParameters) {
+ last;
+ }
+ if ($first) { $first = 0; }
+ else { $functionString .= ", "; }
+ my $paramName = $parameter->name;
+ my $paramType = $parameter->type;
+
+ # This is a bit of a hack... we need to convert parameters to methods on SVG lists
+ # of POD types which are items in the list to appropriate SVGList<> instances
+ if ($returnsListItemPodType && $paramType . "List" eq $implClassName) {
+ $paramName = "SVGPODListItem<" . GetNativeType($paramType, 1) . ">::copy($paramName)";
+ }
+
+ if ($parameter->type eq "NodeFilter") {
+ $functionString .= "$paramName.get()";
+ } else {
+ $functionString .= $paramName;
+ }
+
+ if ($parameter->extendedAttributes->{"Return"}) {
+ $nodeToReturn = $parameter->name;
+ }
+ $index++;
+ }
+
+ if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
+ $functionString .= ", " if not $first;
+ $functionString .= "&callStack";
+ if ($first) { $first = 0; }
+ }
+
+ if (@{$function->raisesExceptions}) {
+ $functionString .= ", " if not $first;
+ $functionString .= "ec";
+ }
+ $functionString .= ")";
+
+ if ((IsRefPtrType($returnType) || $returnsListItemPodType) &&
+ !$nodeToReturn) {
+ # We don't use getPtr when $nodeToReturn because that situation is
+ # special-cased below to return a bool.
+ $implIncludes{"wtf/GetPtr.h"} = 1;
+ $functionString = "WTF::getPtr(" . $functionString . ")";
+ }
+
+ if ($nodeToReturn) {
+ # Special case for insertBefore, replaceChild, removeChild and
+ # appendChild functions from Node.
+ $result .= $indent . "bool success = $functionString;\n";
+ if (@{$function->raisesExceptions}) {
+ $result .= GenerateSetDOMException($indent);
+ }
+ $result .= $indent . "if (success)\n";
+ $result .= $indent . " " .
+ "return V8Proxy::NodeToV8Object($nodeToReturn);\n";
+ $result .= $indent . "return v8::Null();\n";
+ return $result;
+ } elsif ($returnType eq "void") {
+ $result .= $indent . "$functionString;\n";
+ } elsif ($copyFirst) {
+ $result .=
+ $indent . GetNativeType($returnType, 0) . " result = *imp;\n" .
+ $indent . "$functionString;\n";
+ } elsif ($returnsListItemPodType) {
+ $result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
+ } else {
+ $result .= $indent . $nativeReturnType . " result = $functionString;\n";
+ }
+
+ if (@{$function->raisesExceptions}) {
+ $result .= GenerateSetDOMException($indent);
+ }
+
+ my $return = "result";
+ if (IsRefPtrType($returnType) || $returnsListItemPodType) {
+ $implIncludes{"wtf/GetPtr.h"} = 1;
+ $return = "WTF::getPtr(" . $return . ")";
+ }
+
+ # If the return type is a POD type, separate out the wrapper generation
+ if ($returnsListItemPodType) {
+ $result .= $indent . "V8SVGPODTypeWrapper<" . $nativeReturnType . ">* wrapper = new ";
+ $result .= "V8SVGPODTypeWrapperCreatorForList<" . $nativeReturnType . ">($return, imp->associatedAttributeName());\n";
+ $return = "wrapper";
+ } elsif ($returnsPodType) {
+ $result .= $indent . "V8SVGPODTypeWrapper<" . $nativeReturnType . ">* wrapper = ";
+ $result .= GenerateSVGStaticPodTypeWrapper($returnType, $return) . ";\n";
+ $return = "wrapper";
+ }
+
+ my $generatedSVGContextRetrieval = 0;
+ # If the return type needs an SVG context, output it
+ if (IsSVGTypeNeedingContextParameter($returnType)) {
+ $result .= GenerateSVGContextAssignment($implClassName, $return, $indent);
+ $generatedSVGContextRetrieval = 1;
+ }
+
+ if (IsSVGTypeNeedingContextParameter($implClassName) && $implClassName =~ /List$/ && IsSVGListMutator($name)) {
+ if (!$generatedSVGContextRetrieval) {
+ $result .= GenerateSVGContextRetrieval($implClassName, $indent);
+ $generatedSVGContextRetrieval = 1;
+ }
+
+ $result .= $indent . "context->svgAttributeChanged(imp->associatedAttributeName());\n";
+ $implIncludes{"SVGElement.h"} = 1;
+ }
+
+ # If the implementing class is a POD type, commit changes
+ if ($isPodType) {
+ if (!$generatedSVGContextRetrieval) {
+ $result .= GenerateSVGContextRetrieval($implClassName, $indent);
+ $generatedSVGContextRetrieval = 1;
+ }
+
+ $result .= $indent . "imp_wrapper->commitChange(imp_instance, context);\n";
+ }
+
+ if ($returnsPodType) {
+ my $classIndex = uc($returnType);
+ $result .= $indent . "return V8Proxy::ToV8Object(V8ClassIndex::$classIndex, wrapper);\n";
+ } else {
+ $result .= $indent . "return " . NativeToJSValue($function->signature, $return) . ";\n";
+ }
+
+ return $result;
+}
+
+
+# Get the class name used for printing javascript DOM-object wrappers.
+sub GetClassName
+{
+ my $type = shift;
+ return "HTMLCollection" if $type eq "UndetectableHTMLCollection";
+ return $type;
+}
+
+
+sub GetNativeTypeFromSignature
+{
+ my $signature = shift;
+ my $isParameter = shift;
+
+ my $type = $codeGenerator->StripModule($signature->type);
+
+ return GetNativeType($type, $isParameter);
+}
+
+sub IsRefPtrType
+{
+ my $type = shift;
+ return 1 if $type eq "Attr";
+ return 1 if $type eq "CanvasGradient";
+ return 1 if $type eq "ClientRect";
+ return 1 if $type eq "ClientRectList";
+ return 1 if $type eq "CDATASection";
+ return 1 if $type eq "Comment";
+ return 1 if $type eq "CSSRule";
+ return 1 if $type eq "CSSStyleRule";
+ return 1 if $type eq "CSSCharsetRule";
+ return 1 if $type eq "CSSImportRule";
+ return 1 if $type eq "CSSMediaRule";
+ return 1 if $type eq "CSSFontFaceRule";
+ return 1 if $type eq "CSSPageRule";
+ return 1 if $type eq "CSSPrimitiveValue";
+ return 1 if $type eq "CSSStyleSheet";
+ return 1 if $type eq "CSSStyleDeclaration";
+ return 1 if $type eq "CSSValue";
+ return 1 if $type eq "CSSRuleList";
+ return 1 if $type eq "Document";
+ return 1 if $type eq "DocumentFragment";
+ return 1 if $type eq "DocumentType";
+ return 1 if $type eq "Element";
+ return 1 if $type eq "EntityReference";
+ return 1 if $type eq "Event";
+ return 1 if $type eq "HTMLCollection";
+ return 1 if $type eq "HTMLDocument";
+ return 1 if $type eq "HTMLElement";
+ return 1 if $type eq "HTMLOptionsCollection";
+ return 1 if $type eq "ImageData";
+ return 1 if $type eq "MediaError";
+ return 1 if $type eq "MimeType";
+ return 1 if $type eq "Node";
+ return 1 if $type eq "NodeList";
+ return 1 if $type eq "NodeFilter";
+ return 1 if $type eq "NodeIterator";
+ return 1 if $type eq "NSResolver";
+ return 1 if $type eq "Plugin";
+ return 1 if $type eq "ProcessingInstruction";
+ return 1 if $type eq "Range";
+ return 1 if $type eq "Text";
+ return 1 if $type eq "TextMetrics";
+ return 1 if $type eq "TimeRanges";
+ return 1 if $type eq "TreeWalker";
+ return 1 if $type eq "WebKitCSSMatrix";
+ return 1 if $type eq "WebKitPoint";
+ return 1 if $type eq "XPathExpression";
+ return 1 if $type eq "XPathNSResolver";
+ return 1 if $type eq "XPathResult";
+
+ return 1 if $type eq "SVGAngle";
+ return 1 if $type eq "SVGElementInstance";
+ return 1 if $type eq "SVGElementInstanceList";
+ return 1 if $type =~ /^SVGPathSeg/;
+
+ return 1 if $type =~ /^SVGAnimated/;
+
+ return 0;
+}
+
+sub IsVideoClassName
+{
+ my $class = shift;
+ return 1 if $class eq "V8HTMLAudioElement";
+ return 1 if $class eq "V8HTMLMediaElement";
+ return 1 if $class eq "V8HTMLSourceElement";
+ return 1 if $class eq "V8HTMLVideoElement";
+ return 1 if $class eq "V8MediaError";
+ return 1 if $class eq "V8TimeRanges";
+
+ return 0;
+}
+
+sub IsWorkerClassName
+{
+ my $class = shift;
+ return 1 if $class eq "V8Worker";
+ return 1 if $class eq "V8WorkerContext";
+ return 1 if $class eq "V8WorkerLocation";
+ return 1 if $class eq "V8WorkerNavigator";
+
+ return 0;
+}
+
+sub GetNativeType
+{
+ my $type = shift;
+ my $isParameter = shift;
+
+ if ($type eq "float" or $type eq "AtomicString" or $type eq "double") {
+ return $type
+ }
+
+ return "int" if $type eq "short" or $type eq "unsigned short";
+ return "int" if $type eq "long" or $type eq "unsigned long";
+ return "unsigned long long" if $type eq "unsigned long long";
+ return "bool" if $type eq "boolean";
+ return "String" if $type eq "DOMString";
+ return "Range::CompareHow" if $type eq "CompareHow";
+ return "FloatRect" if $type eq "SVGRect";
+ return "FloatPoint" if $type eq "SVGPoint";
+ return "TransformationMatrix" if $type eq "SVGMatrix";
+ return "SVGTransform" if $type eq "SVGTransform";
+ return "SVGLength" if $type eq "SVGLength";
+ return "double" if $type eq "SVGNumber";
+ return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
+ return "DOMTimeStamp" if $type eq "DOMTimeStamp";
+ return "unsigned" if $type eq "RGBColor";
+ return "Node*" if $type eq "EventTarget" and $isParameter;
+
+ return "String" if $type eq "DOMUserData"; # temporary hack, TODO
+
+ # temporary hack
+ return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
+
+ return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter;
+
+ # Default, assume native type is a pointer with same type name as idl type
+ return "${type}*";
+}
+
+
+my %typeCanFailConversion = (
+ "AtomicString" => 0,
+ "Attr" => 1,
+ "CompareHow" => 0,
+ "DOMString" => 0,
+ "DOMWindow" => 0,
+ "DocumentType" => 0,
+ "Element" => 0,
+ "Event" => 0,
+ "EventListener" => 0,
+ "EventTarget" => 0,
+ "Geoposition" => 0,
+ "HTMLElement" => 0,
+ "HTMLOptionElement" => 0,
+ "Node" => 0,
+ "NodeFilter" => 0,
+ "MessagePort" => 0,
+ "NSResolver" => 0,
+ "PositionError" => 0,
+ "Range" => 0,
+ "SQLResultSet" => 0,
+ "SVGAngle" => 0,
+ "SVGElement" => 0,
+ "SVGLength" => 0,
+ "SVGMatrix" => 0,
+ "SVGNumber" => 0,
+ "SVGPaintType" => 0,
+ "SVGPathSeg" => 0,
+ "SVGPoint" => 0,
+ "SVGRect" => 0,
+ "SVGTransform" => 0,
+ "TouchList" => 0,
+ "VoidCallback" => 1,
+ "WebKitCSSMatrix" => 0,
+ "WebKitPoint" => 0,
+ "XPathEvaluator" => 0,
+ "XPathNSResolver" => 0,
+ "XPathResult" => 0,
+ "boolean" => 0,
+ "double" => 0,
+ "float" => 0,
+ "long" => 0,
+ "unsigned long" => 0,
+ "unsigned short" => 0,
+);
+
+
+sub TranslateParameter
+{
+ my $signature = shift;
+
+ # The IDL uses some pseudo-types which don't really exist.
+ if ($signature->type eq "TimeoutHandler") {
+ $signature->type("DOMString");
+ }
+}
+
+sub BasicTypeCanFailConversion
+{
+ # As can been seen from the above, no basic types can fail conversion.
+ return 0;
+}
+
+sub TypeCanFailConversion
+{
+ my $signature = shift;
+
+ my $type = $codeGenerator->StripModule($signature->type);
+
+ $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
+
+ return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type};
+
+ die "Don't know whether a JS value can fail conversion to type $type.";
+}
+
+sub JSValueToNative
+{
+ my $signature = shift;
+ my $value = shift;
+ my $okParam = shift;
+ my $maybeOkParam = $okParam ? ", ${okParam}" : "";
+
+ my $type = $codeGenerator->StripModule($signature->type);
+
+ return "$value" if $type eq "JSObject";
+ return "$value->BooleanValue()" if $type eq "boolean";
+ return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $type eq "double";
+ return "$value->NumberValue()" if $type eq "SVGNumber";
+
+ return "ToInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short" or $type eq "long";
+ return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow";
+ return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())" if $type eq "SVGPaintType";
+
+ return "ToWebCoreString($value)" if $type eq "AtomicString" or $type eq "DOMUserData";
+ if ($type eq "DOMString") {
+ return "valueToStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"};
+ return "valueToStringWithNullOrUndefinedCheck($value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"};
+ return "ToWebCoreString($value)";
+ }
+
+ if ($type eq "NodeFilter") {
+ return "V8Proxy::ToNativeNodeFilter($value)";
+ }
+
+ if ($type eq "SVGRect") {
+ $implIncludes{"FloatRect.h"} = 1;
+ }
+
+ if ($type eq "SVGPoint") {
+ $implIncludes{"FloatPoint.h"} = 1;
+ }
+
+ # Default, assume autogenerated type conversion routines
+ $implIncludes{"v8_proxy.h"} = 1;
+ if ($type eq "EventTarget") {
+ $implIncludes{"V8Node.h"} = 1;
+
+ # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget.
+ return "V8Node::HasInstance($value) ? V8Proxy::DOMWrapperToNode<Node>($value) : 0";
+ }
+
+ AddIncludesForType($type);
+ # $implIncludes{"$type.h"} = 1 unless AvoidInclusionOfType($type);
+
+ if (IsDOMNodeType($type)) {
+ $implIncludes{"V8${type}.h"} = 1;
+
+ # Perform type checks on the parameter, if it is expected Node type,
+ # return NULL.
+ return "V8${type}::HasInstance($value) ? V8Proxy::DOMWrapperToNode<${type}>($value) : 0";
+
+ } else {
+ # TODO: Temporary to avoid Window name conflict.
+ my $classIndex = uc($type);
+ my $implClassName = ${type};
+
+ $implIncludes{"V8$type.h"} = 1;
+
+ if ($codeGenerator->IsPodType($type)) {
+ my $nativeType = GetNativeType($type);
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+
+ # TODO(jhass): perform type checking like others???
+ return "*V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<${nativeType}> >(V8ClassIndex::${classIndex}, $value)"
+ }
+
+ $implIncludes{"V8${type}.h"} = 1;
+
+ # Perform type checks on the parameter, if it is expected Node type,
+ # return NULL.
+ return "V8${type}::HasInstance($value) ? V8Proxy::ToNativeObject<${implClassName}>(V8ClassIndex::${classIndex}, $value) : 0";
+ }
+}
+
+
+sub GetV8HeaderName
+{
+ my $type = shift;
+ return "V8" . GetImplementationFileName($type);
+}
+
+
+sub CreateCustomSignature
+{
+ my $function = shift;
+ my $count = @{$function->parameters};
+ my $name = $function->signature->name;
+ my $result = " const int ${name}_argc = ${count};\n" .
+ " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { ";
+ my $first = 1;
+ foreach my $parameter (@{$function->parameters}) {
+ if ($first) { $first = 0; }
+ else { $result .= ", "; }
+ if (IsWrapperType($parameter->type)) {
+ my $type = $parameter->type;
+ my $header = GetV8HeaderName($type);
+ $implIncludes{$header} = 1;
+ $result .= "V8${type}::GetRawTemplate()";
+ } else {
+ $result .= "v8::Handle<v8::FunctionTemplate>()";
+ }
+ }
+ $result .= " };\n";
+ $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n";
+ return $result;
+}
+
+
+sub RequiresCustomSignature
+{
+ my $function = shift;
+ # No signature needed for Custom function
+ if ($function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"V8Custom"}) {
+ return 0;
+ }
+
+ foreach my $parameter (@{$function->parameters}) {
+ if (IsWrapperType($parameter->type)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+my %non_wrapper_types = (
+ 'float' => 1,
+ 'AtomicString' => 1,
+ 'double' => 1,
+ 'short' => 1,
+ 'unsigned short' => 1,
+ 'long' => 1,
+ 'unsigned long' => 1,
+ 'boolean' => 1,
+ 'DOMString' => 1,
+ 'CompareHow' => 1,
+ 'SVGRect' => 1,
+ 'SVGPoint' => 1,
+ 'SVGMatrix' => 1,
+ 'SVGTransform' => 1,
+ 'SVGLength' => 1,
+ 'SVGNumber' => 1,
+ 'SVGPaintType' => 1,
+ 'DOMTimeStamp' => 1,
+ 'JSObject' => 1,
+ 'EventTarget' => 1,
+ 'NodeFilter' => 1,
+ 'EventListener' => 1
+);
+
+
+sub IsWrapperType
+{
+ my $type = $codeGenerator->StripModule(shift);
+ return !($non_wrapper_types{$type});
+}
+
+sub IsDOMNodeType
+{
+ my $type = shift;
+
+ return 1 if $type eq 'Attr';
+ return 1 if $type eq 'CDATASection';
+ return 1 if $type eq 'Comment';
+ return 1 if $type eq 'Document';
+ return 1 if $type eq 'DocumentFragment';
+ return 1 if $type eq 'DocumentType';
+ return 1 if $type eq 'Element';
+ return 1 if $type eq 'EntityReference';
+ return 1 if $type eq 'HTMLCanvasElement';
+ return 1 if $type eq 'HTMLDocument';
+ return 1 if $type eq 'HTMLElement';
+ return 1 if $type eq 'HTMLFormElement';
+ return 1 if $type eq 'HTMLTableCaptionElement';
+ return 1 if $type eq 'HTMLTableSectionElement';
+ return 1 if $type eq 'Node';
+ return 1 if $type eq 'ProcessingInstruction';
+ return 1 if $type eq 'SVGElement';
+ return 1 if $type eq 'SVGDocument';
+ return 1 if $type eq 'SVGSVGElement';
+ return 1 if $type eq 'SVGUseElement';
+ return 1 if $type eq 'Text';
+
+ return 0;
+}
+
+
+sub NativeToJSValue
+{
+ my $signature = shift;
+ my $value = shift;
+ my $type = $codeGenerator->StripModule($signature->type);
+ my $className= "V8$type";
+
+ return "v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp";
+ return "$value ? v8::True() : v8::False()" if $type eq "boolean";
+ return "v8::Undefined()" if $type eq "void";
+
+ # For all the types where we use 'int' as the representation type,
+ # we use Integer::New which has a fast Smi conversion check.
+ return "v8::Integer::New($value)" if GetNativeType($type) eq "int";
+
+ return "v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
+
+ if ($codeGenerator->IsStringType($type)) {
+ my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
+ if (defined $conv) {
+ return "v8StringOrNull($value)" if $conv eq "Null";
+ return "v8StringOrUndefined($value)" if $conv eq "Undefined";
+ return "v8StringOrFalse($value)" if $conv eq "False";
+
+ die "Unknown value for ConvertNullStringTo extended attribute";
+ }
+ return "v8String($value)";
+ }
+
+ # V8 specific.
+ my $implClassName = $type;
+ AddIncludesForType($type);
+ # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type);
+
+ # special case for non-DOM node interfaces
+ if (IsDOMNodeType($type)) {
+ return "V8Proxy::NodeToV8Object($value)";
+ }
+
+ if ($type eq "EventTarget" or $type eq "SVGElementInstance") {
+ return "V8Proxy::EventTargetToV8Object($value)";
+ }
+
+ if ($type eq "Event") {
+ return "V8Proxy::EventToV8Object($value)";
+ }
+
+ if ($type eq "EventListener") {
+ return "V8Proxy::EventListenerToV8Object($value)";
+ }
+
+ if ($type eq "RGBColor") {
+ return "V8Proxy::ToV8Object(V8ClassIndex::RGBCOLOR, new RGBColor($value))";
+ }
+
+ if ($type eq "WorkerLocation" or $type eq "WorkerNavigator") {
+ $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
+ my $classIndex = uc($type);
+
+ return "WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::$classIndex, $value)";
+ }
+
+ else {
+ $implIncludes{"wtf/RefCounted.h"} = 1;
+ $implIncludes{"wtf/RefPtr.h"} = 1;
+ my $classIndex = uc($type);
+
+ if ($codeGenerator->IsPodType($type)) {
+ $value = GenerateSVGStaticPodTypeWrapper($type, $value);
+ }
+
+ return "V8Proxy::ToV8Object(V8ClassIndex::$classIndex, $value)";
+ }
+}
+
+sub GenerateSVGStaticPodTypeWrapper {
+ my $type = shift;
+ my $value = shift;
+
+ $implIncludes{"V8$type.h"}=1;
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+
+ my $nativeType = GetNativeType($type);
+ return "new V8SVGStaticPODTypeWrapper<$nativeType>($value)";
+}
+
+# Internal helper
+sub WriteData
+{
+ if (defined($IMPL)) {
+ # Write content to file.
+ print $IMPL @implContentHeader;
+
+ print $IMPL @implFixedHeader;
+
+ foreach my $implInclude (sort keys(%implIncludes)) {
+ my $checkType = $implInclude;
+ $checkType =~ s/\.h//;
+
+ print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
+ }
+
+ print $IMPL "\n";
+ print $IMPL @implContentDecls;
+ print $IMPL @implContent;
+ close($IMPL);
+ undef($IMPL);
+
+ %implIncludes = ();
+ @implFixedHeader = ();
+ @implHeaderContent = ();
+ @implContentDecls = ();
+ @implContent = ();
+ }
+
+ if (defined($HEADER)) {
+ # Write content to file.
+ print $HEADER @headerContent;
+ close($HEADER);
+ undef($HEADER);
+
+ @headerContent = ();
+ }
+}
+
+sub IsSVGTypeNeedingContextParameter
+{
+ my $implClassName = shift;
+
+ if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) {
+ return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGColor/ or $implClassName =~ /SVGDocument/;
+ }
+
+ return 0;
+}
+
+sub GenerateSVGContextAssignment
+{
+ my $srcType = shift;
+ my $value = shift;
+ my $indent = shift;
+
+ $result = GenerateSVGContextRetrieval($srcType, $indent);
+ $result .= $indent . "V8Proxy::SetSVGContext($value, context);\n";
+
+ return $result;
+}
+
+sub GenerateSVGContextRetrieval
+{
+ my $srcType = shift;
+ my $indent = shift;
+
+ my $srcIsPodType = $codeGenerator->IsPodType($srcType);
+
+ my $srcObject = "imp";
+ if ($srcIsPodType) {
+ $srcObject = "imp_wrapper";
+ }
+
+ my $contextDecl;
+
+ if (IsSVGTypeNeedingContextParameter($srcType)) {
+ $contextDecl = "V8Proxy::GetSVGContext($srcObject)";
+ } else {
+ $contextDecl = $srcObject;
+ }
+
+ return $indent . "SVGElement* context = $contextDecl;\n";
+}
+
+sub IsSVGListMutator
+{
+ my $functionName = shift;
+
+ return 1 if $functionName eq "clear";
+ return 1 if $functionName eq "initialize";
+ return 1 if $functionName eq "insertItemBefore";
+ return 1 if $functionName eq "replaceItem";
+ return 1 if $functionName eq "removeItem";
+ return 1 if $functionName eq "appendItem";
+
+ return 0;
+}
+
+sub IsSVGListMethod
+{
+ my $functionName = shift;
+
+ return 1 if $functionName eq "getFirst";
+ return 1 if $functionName eq "getLast";
+ return 1 if $functionName eq "getItem";
+
+ return IsSVGListMutator($functionName);
+}
+
+sub IsSVGListTypeNeedingSpecialHandling
+{
+ my $className = shift;
+
+ return 1 if $className eq "SVGPointList";
+ return 1 if $className eq "SVGTransformList";
+
+ return 0;
+}
+
+sub DebugPrint
+{
+ my $output = shift;
+
+ print $output;
+ print "\n";
+}
diff --git a/V8Binding/scripts/IDLParser.pm b/V8Binding/scripts/IDLParser.pm
new file mode 100644
index 0000000..eb0eab5
--- /dev/null
+++ b/V8Binding/scripts/IDLParser.pm
@@ -0,0 +1,441 @@
+#
+# KDOM IDL parser
+#
+# Copyright (C) 2005 Nikolas Zimmermann <wildfox@kde.org>
+#
+# This file is part of the KDE project
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# aint with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+package IDLParser;
+
+use IDLStructure;
+
+use constant MODE_UNDEF => 0; # Default mode.
+
+use constant MODE_MODULE => 10; # 'module' section
+use constant MODE_INTERFACE => 11; # 'interface' section
+use constant MODE_EXCEPTION => 12; # 'exception' section
+use constant MODE_ALIAS => 13; # 'alias' section
+
+# Helper variables
+my @temporaryContent = "";
+
+my $parseMode = MODE_UNDEF;
+my $preservedParseMode = MODE_UNDEF;
+
+my $beQuiet; # Should not display anything on STDOUT?
+my $document = 0; # Will hold the resulting 'idlDocument'
+
+my $directive = "";
+
+# Default Constructor
+sub new
+{
+ my $object = shift;
+ my $reference = { };
+
+ $document = 0;
+ $beQuiet = shift;
+
+ bless($reference, $object);
+ return $reference;
+}
+
+
+sub ParseInheritance
+{
+ my $object = shift;
+ my $fileName = shift;
+ my $defines = shift;
+ my $preprocessor = shift;
+
+ $directive = "inheritance";
+ return $object->ParseImpl($fileName, $defines, $preprocessor);
+}
+
+# Returns the parsed 'idlDocument'
+sub Parse
+{
+ my $object = shift;
+ my $fileName = shift;
+ my $defines = shift;
+ my $preprocessor = shift;
+
+ $directive = "";
+ return $object->ParseImpl($fileName, $defines, $preprocessor);
+}
+
+sub ParseImpl
+{
+ my $object = shift;
+ my $fileName = shift;
+ my $defines = shift;
+ my $preprocessor = shift;
+
+ if (!$preprocessor) {
+ $preprocessor = "/usr/bin/gcc -E -P -x c++";
+ }
+
+ if (!$defines) {
+ $defines = "";
+ }
+
+ print " | *** Starting to parse $fileName...\n |\n" unless $beQuiet;
+
+ open FILE, $preprocessor . " " . join(" ", (map { "-D$_" } split(/ /, $defines))) . " ". $fileName . "|" or die "Could not open $fileName";
+ my @documentContent = <FILE>;
+ close FILE;
+
+ my $dataAvailable = 0;
+
+ # Simple IDL Parser (tm)
+ foreach (@documentContent) {
+ my $newParseMode = $object->DetermineParseMode($_);
+
+ if ($newParseMode ne MODE_UNDEF) {
+ if ($dataAvailable eq 0) {
+ $dataAvailable = 1; # Start node building...
+ } else {
+ $object->ProcessSection();
+ }
+ }
+
+ # Update detected data stream mode...
+ if ($newParseMode ne MODE_UNDEF) {
+ $parseMode = $newParseMode;
+ }
+
+ push(@temporaryContent, $_);
+ }
+
+ # Check if there is anything remaining to parse...
+ if (($parseMode ne MODE_UNDEF) and ($#temporaryContent > 0)) {
+ $object->ProcessSection();
+ }
+
+ print " | *** Finished parsing!\n" unless $beQuiet;
+
+ $document->fileName($fileName);
+
+ return $document;
+}
+
+sub ParseModule
+{
+ my $object = shift;
+ my $dataNode = shift;
+
+ print " |- Trying to parse module...\n" unless $beQuiet;
+
+ my $data = join("", @temporaryContent);
+ $data =~ /$IDLStructure::moduleSelector/;
+
+ my $moduleName = (defined($1) ? $1 : die("Parsing error!\nSource:\n$data\n)"));
+ $dataNode->module($moduleName);
+
+ print " |----> Module; NAME \"$moduleName\"\n |-\n |\n" unless $beQuiet;
+}
+
+sub dumpExtendedAttributes
+{
+ my $padStr = shift;
+ my $attrs = shift;
+
+ if (!%{$attrs}) {
+ return "";
+ }
+
+ my @temp;
+ while (($name, $value) = each(%{$attrs})) {
+ push(@temp, "$name=$value");
+ }
+
+ return $padStr . "[" . join(", ", @temp) . "]";
+}
+
+sub parseExtendedAttributes
+{
+ my $str = shift;
+ $str =~ s/\[\s*(.*)\]/$1/g;
+
+ my %attrs = ();
+
+ foreach my $value (split(/\s*,\s*/, $str)) {
+ ($name,$value) = split(/\s*=\s*/, $value, 2);
+
+ # Attributes with no value are set to be true
+ $value = 1 unless defined $value;
+ $attrs{$name} = $value;
+ }
+
+ return \%attrs;
+}
+
+sub ParseInterface
+{
+ my $object = shift;
+ my $dataNode = shift;
+ my $sectionName = shift;
+
+ my $data = join("", @temporaryContent);
+
+ # Look for end-of-interface mark
+ $data =~ /};/g;
+ $data = substr($data, index($data, $sectionName), pos($data) - length($data));
+
+ $data =~ s/[\n\r]/ /g;
+
+ # Beginning of the regexp parsing magic
+ if ($sectionName eq "exception") {
+ print " |- Trying to parse exception...\n" unless $beQuiet;
+
+ my $exceptionName = "";
+ my $exceptionData = "";
+ my $exceptionDataName = "";
+ my $exceptionDataType = "";
+
+ # Match identifier of the exception, and enclosed data...
+ $data =~ /$IDLStructure::exceptionSelector/;
+ $exceptionName = (defined($1) ? $1 : die("Parsing error!\nSource:\n$data\n)"));
+ $exceptionData = (defined($2) ? $2 : die("Parsing error!\nSource:\n$data\n)"));
+
+ ('' =~ /^/); # Reset variables needed for regexp matching
+
+ # ... parse enclosed data (get. name & type)
+ $exceptionData =~ /$IDLStructure::exceptionSubSelector/;
+ $exceptionDataType = (defined($1) ? $1 : die("Parsing error!\nSource:\n$data\n)"));
+ $exceptionDataName = (defined($2) ? $2 : die("Parsing error!\nSource:\n$data\n)"));
+
+ # Fill in domClass datastructure
+ $dataNode->name($exceptionName);
+
+ my $newDataNode = new domAttribute();
+ $newDataNode->type("readonly attribute");
+ $newDataNode->signature(new domSignature());
+
+ $newDataNode->signature->name($exceptionDataName);
+ $newDataNode->signature->type($exceptionDataType);
+
+ my $arrayRef = $dataNode->attributes;
+ push(@$arrayRef, $newDataNode);
+
+ print " |----> Exception; NAME \"$exceptionName\" DATA TYPE \"$exceptionDataType\" DATA NAME \"$exceptionDataName\"\n |-\n |\n" unless $beQuiet;
+ } elsif ($sectionName eq "interface") {
+ print " |- Trying to parse interface...\n" unless $beQuiet;
+
+ my $interfaceName = "";
+ my $interfaceData = "";
+
+ # Match identifier of the interface, and enclosed data...
+ $data =~ /$IDLStructure::interfaceSelector/;
+
+ $interfaceExtendedAttributes = (defined($1) ? $1 : " "); chop($interfaceExtendedAttributes);
+ $interfaceName = (defined($2) ? $2 : die("Parsing error!\nSource:\n$data\n)"));
+ $interfaceBase = (defined($3) ? $3 : "");
+ $interfaceData = (defined($4) ? $4 : die("Parsing error!\nSource:\n$data\n)"));
+
+ # Fill in known parts of the domClass datastructure now...
+ $dataNode->name($interfaceName);
+ $dataNode->extendedAttributes(parseExtendedAttributes($interfaceExtendedAttributes));
+
+ # Inheritance detection
+ my @interfaceParents = split(/,/, $interfaceBase);
+ foreach(@interfaceParents) {
+ my $line = $_;
+ $line =~ s/\s*//g;
+
+ my $arrayRef = $dataNode->parents;
+ push(@$arrayRef, $line);
+ }
+
+ return if ($directive eq "inheritance");
+
+ $interfaceData =~ s/[\n\r]/ /g;
+ my @interfaceMethods = split(/;/, $interfaceData);
+
+ foreach my $line (@interfaceMethods) {
+ if ($line =~ /[ \t]attribute[ \t]/) {
+ $line =~ /$IDLStructure::interfaceAttributeSelector/;
+
+ my $attributeType = (defined($1) ? $1 : die("Parsing error!\nSource:\n$line\n)"));
+ my $attributeExtendedAttributes = (defined($2) ? $2 : " "); chop($attributeExtendedAttributes);
+
+ my $attributeDataType = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)"));
+ my $attributeDataName = (defined($4) ? $4 : die("Parsing error!\nSource:\n$line\n)"));
+
+ ('' =~ /^/); # Reset variables needed for regexp matching
+
+ $line =~ /$IDLStructure::getterRaisesSelector/;
+ my $getterException = (defined($1) ? $1 : "");
+
+ $line =~ /$IDLStructure::setterRaisesSelector/;
+ my $setterException = (defined($1) ? $1 : "");
+
+ my $newDataNode = new domAttribute();
+ $newDataNode->type($attributeType);
+ $newDataNode->signature(new domSignature());
+
+ $newDataNode->signature->name($attributeDataName);
+ $newDataNode->signature->type($attributeDataType);
+ $newDataNode->signature->extendedAttributes(parseExtendedAttributes($attributeExtendedAttributes));
+
+ my $arrayRef = $dataNode->attributes;
+ push(@$arrayRef, $newDataNode);
+
+ print " | |> Attribute; TYPE \"$attributeType\" DATA NAME \"$attributeDataName\" DATA TYPE \"$attributeDataType\" GET EXCEPTION? \"$getterException\" SET EXCEPTION? \"$setterException\"" .
+ dumpExtendedAttributes("\n | ", $newDataNode->signature->extendedAttributes) . "\n" unless $beQuiet;
+
+ $getterException =~ s/\s+//g;
+ $setterException =~ s/\s+//g;
+ @{$newDataNode->getterExceptions} = split(/,/, $getterException);
+ @{$newDataNode->setterExceptions} = split(/,/, $setterException);
+ } elsif (($line !~ s/^\s*$//g) and ($line !~ /^\s*const/)) {
+ $line =~ /$IDLStructure::interfaceMethodSelector/ or die "Parsing error!\nSource:\n$line\n)";
+
+ my $methodExtendedAttributes = (defined($1) ? $1 : " "); chop($methodExtendedAttributes);
+ my $methodType = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)"));
+ my $methodName = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)"));
+ my $methodSignature = (defined($4) ? $4 : die("Parsing error!\nSource:\n$line\n)"));
+
+ ('' =~ /^/); # Reset variables needed for regexp matching
+
+ $line =~ /$IDLStructure::raisesSelector/;
+ my $methodException = (defined($1) ? $1 : "");
+
+ my $newDataNode = new domFunction();
+
+ $newDataNode->signature(new domSignature());
+ $newDataNode->signature->name($methodName);
+ $newDataNode->signature->type($methodType);
+ $newDataNode->signature->extendedAttributes(parseExtendedAttributes($methodExtendedAttributes));
+
+ print " | |- Method; TYPE \"$methodType\" NAME \"$methodName\" EXCEPTION? \"$methodException\"" .
+ dumpExtendedAttributes("\n | ", $newDataNode->signature->extendedAttributes) . "\n" unless $beQuiet;
+
+ $methodException =~ s/\s+//g;
+ @{$newDataNode->raisesExceptions} = split(/,/, $methodException);
+
+ my @params = split(/,/, $methodSignature);
+ foreach(@params) {
+ my $line = $_;
+
+ $line =~ /$IDLStructure::interfaceParameterSelector/;
+ my $paramExtendedAttributes = (defined($1) ? $1 : " "); chop($paramExtendedAttributes);
+ my $paramType = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)"));
+ my $paramName = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)"));
+
+ my $paramDataNode = new domSignature();
+ $paramDataNode->name($paramName);
+ $paramDataNode->type($paramType);
+ $paramDataNode->extendedAttributes(parseExtendedAttributes($paramExtendedAttributes));
+
+ my $arrayRef = $newDataNode->parameters;
+ push(@$arrayRef, $paramDataNode);
+
+ print " | |> Param; TYPE \"$paramType\" NAME \"$paramName\"" .
+ dumpExtendedAttributes("\n | ", $paramDataNode->extendedAttributes) . "\n" unless $beQuiet;
+ }
+
+ my $arrayRef = $dataNode->functions;
+ push(@$arrayRef, $newDataNode);
+ } elsif ($line =~ /^\s*const/) {
+ $line =~ /$IDLStructure::constantSelector/;
+ my $constType = (defined($1) ? $1 : die("Parsing error!\nSource:\n$line\n)"));
+ my $constName = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)"));
+ my $constValue = (defined($3) ? $3 : die("Parsing error!\nSource:\n$line\n)"));
+
+ my $newDataNode = new domConstant();
+ $newDataNode->name($constName);
+ $newDataNode->type($constType);
+ $newDataNode->value($constValue);
+
+ my $arrayRef = $dataNode->constants;
+ push(@$arrayRef, $newDataNode);
+
+ print " | |> Constant; TYPE \"$constType\" NAME \"$constName\" VALUE \"$constValue\"\n" unless $beQuiet;
+ }
+ }
+
+ print " |----> Interface; NAME \"$interfaceName\"" .
+ dumpExtendedAttributes("\n | ", $dataNode->extendedAttributes) . "\n |-\n |\n" unless $beQuiet;
+ }
+}
+
+# Internal helper
+sub DetermineParseMode
+{
+ my $object = shift;
+ my $line = shift;
+
+ my $mode = MODE_UNDEF;
+ if ($_ =~ /module/) {
+ $mode = MODE_MODULE;
+ } elsif ($_ =~ /interface/) {
+ $mode = MODE_INTERFACE;
+ } elsif ($_ =~ /exception/) {
+ $mode = MODE_EXCEPTION;
+ } elsif ($_ =~ /alias/) {
+ $mode = MODE_ALIAS;
+ }
+
+ return $mode;
+}
+
+# Internal helper
+sub ProcessSection
+{
+ my $object = shift;
+
+ if ($parseMode eq MODE_MODULE) {
+ die ("Two modules in one file! Fatal error!\n") if ($document ne 0);
+ $document = new idlDocument();
+ $object->ParseModule($document);
+ } elsif ($parseMode eq MODE_INTERFACE) {
+ my $node = new domClass();
+ $object->ParseInterface($node, "interface");
+
+ die ("No module specified! Fatal Error!\n") if ($document eq 0);
+ my $arrayRef = $document->classes;
+ push(@$arrayRef, $node);
+ } elsif($parseMode eq MODE_EXCEPTION) {
+ my $node = new domClass();
+ $object->ParseInterface($node, "exception");
+
+ die ("No module specified! Fatal Error!\n") if ($document eq 0);
+ my $arrayRef = $document->classes;
+ push(@$arrayRef, $node);
+ } elsif($parseMode eq MODE_ALIAS) {
+ print " |- Trying to parse alias...\n" unless $beQuiet;
+
+ my $line = join("", @temporaryContent);
+ $line =~ /$IDLStructure::aliasSelector/;
+
+ my $interfaceName = (defined($1) ? $1 : die("Parsing error!\nSource:\n$line\n)"));
+ my $wrapperName = (defined($2) ? $2 : die("Parsing error!\nSource:\n$line\n)"));
+
+ print " |----> Alias; INTERFACE \"$interfaceName\" WRAPPER \"$wrapperName\"\n |-\n |\n" unless $beQuiet;
+
+ # FIXME: Check if alias is already in aliases
+ my $aliases = $document->aliases;
+ $aliases->{$interfaceName} = $wrapperName;
+ }
+
+ @temporaryContent = "";
+}
+
+1;
diff --git a/V8Binding/scripts/generate-bindings.pl b/V8Binding/scripts/generate-bindings.pl
new file mode 100644
index 0000000..da5d09a
--- /dev/null
+++ b/V8Binding/scripts/generate-bindings.pl
@@ -0,0 +1,69 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2005 Apple Computer, Inc.
+# Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
+#
+# This file is part of WebKit
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public License
+# aint with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+# This script is a temporary hack.
+# Files are generated in the source directory, when they really should go
+# to the DerivedSources directory.
+# This should also eventually be a build rule driven off of .idl files
+# however a build rule only solution is blocked by several radars:
+# <rdar://problems/4251781&4251785>
+
+use strict;
+
+use File::Path;
+use Getopt::Long;
+use Cwd;
+
+use IDLParser;
+use CodeGenerator;
+
+my @idlDirectories;
+my $outputDirectory;
+my $generator;
+my $defines;
+my $preprocessor;
+
+GetOptions('include=s@' => \@idlDirectories,
+ 'outputdir=s' => \$outputDirectory,
+ 'generator=s' => \$generator,
+ 'defines=s' => \$defines,
+ 'preprocessor=s' => \$preprocessor);
+
+my $idlFile = $ARGV[0];
+
+die('Must specify input file.') unless defined($idlFile);
+die('Must specify IDL search path.') unless @idlDirectories;
+die('Must specify generator') unless defined($generator);
+die('Must specify input file.') unless defined($idlFile);
+die('Must specify output directory.') unless defined($outputDirectory);
+die('Must specify defines') unless defined($defines);
+
+$defines =~ s/^\s+|\s+$//g; # trim whitespace
+
+# Parse the given IDL file.
+my $parser = IDLParser->new(1);
+my $document = $parser->Parse($idlFile, $defines, $preprocessor);
+
+# Generate desired output for given IDL file.
+my $codeGen = CodeGenerator->new(\@idlDirectories, $generator, $outputDirectory, 0, $preprocessor);
+$codeGen->ProcessDocument($document, $defines);
diff --git a/V8Binding/v8/DOMObjectsInclude.h b/V8Binding/v8/DOMObjectsInclude.h
new file mode 100644
index 0000000..b7b941e
--- /dev/null
+++ b/V8Binding/v8/DOMObjectsInclude.h
@@ -0,0 +1,191 @@
+// Copyright (c) 2009 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 DOMObjectsInclude_h
+#define DOMObjectsInclude_h
+
+#include "BarInfo.h"
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "CanvasPixelArray.h"
+#include "CanvasRenderingContext2D.h"
+#include "CanvasStyle.h"
+#include "CharacterData.h"
+#include "ClientRect.h"
+#include "ClientRectList.h"
+#include "Clipboard.h"
+#include "Console.h"
+#include "Counter.h"
+#include "CSSCharsetRule.h"
+#include "CSSFontFaceRule.h"
+#include "CSSImportRule.h"
+#include "CSSMediaRule.h"
+#include "CSSPageRule.h"
+#include "CSSRule.h"
+#include "CSSRuleList.h"
+#include "CSSValueList.h"
+#include "CSSStyleRule.h"
+#include "CSSStyleSheet.h"
+#include "CSSVariablesDeclaration.h"
+#include "CSSVariablesRule.h"
+#include "Database.h"
+#include "DocumentType.h"
+#include "DocumentFragment.h"
+#include "DOMCoreException.h"
+#include "DOMImplementation.h"
+#include "DOMParser.h"
+#include "DOMSelection.h"
+#include "DOMStringList.h"
+#include "DOMWindow.h"
+#include "Entity.h"
+#include "EventListener.h"
+#include "EventTarget.h"
+#include "Event.h"
+#include "EventException.h"
+#include "ExceptionCode.h"
+#include "File.h"
+#include "FileList.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "History.h"
+#include "HTMLNames.h"
+#include "HTMLDocument.h"
+#include "HTMLElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLSelectElement.h"
+#include "HTMLOptionsCollection.h"
+#include "ImageData.h"
+#include "InspectorController.h"
+#include "KeyboardEvent.h"
+#include "Location.h"
+#include "MediaError.h"
+#include "MediaList.h"
+#include "MediaPlayer.h"
+#include "MessageChannel.h"
+#include "MessageEvent.h"
+#include "MessagePort.h"
+#include "MimeTypeArray.h"
+#include "MouseEvent.h"
+#include "MutationEvent.h"
+#include "Navigator.h" // for MimeTypeArray
+#include "NodeFilter.h"
+#include "Notation.h"
+#include "NodeList.h"
+#include "NodeIterator.h"
+#include "OverflowEvent.h"
+#include "Page.h"
+#include "Plugin.h"
+#include "PluginArray.h"
+#include "ProcessingInstruction.h"
+#include "ProgressEvent.h"
+#include "Range.h"
+#include "RangeException.h"
+#include "Rect.h"
+#include "RGBColor.h"
+#include "Screen.h"
+#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
+#include "SQLTransaction.h"
+#include "SQLResultSet.h"
+#include "SQLResultSetRowList.h"
+#include "StyleSheet.h"
+#include "StyleSheetList.h"
+#include "TextEvent.h"
+#include "TextMetrics.h"
+#include "TimeRanges.h"
+#include "TreeWalker.h"
+#include "XSLTProcessor.h"
+#include "V8AbstractEventListener.h"
+#include "V8CustomEventListener.h"
+#include "V8DOMWindow.h"
+#include "V8HTMLElement.h"
+#include "V8LazyEventListener.h"
+#include "V8NodeFilterCondition.h"
+#include "V8ObjectEventListener.h"
+#include "WebKitAnimationEvent.h"
+#include "WebKitCSSKeyframeRule.h"
+#include "WebKitCSSKeyframesRule.h"
+#include "WebKitCSSMatrix.h"
+#include "WebKitCSSTransformValue.h"
+#include "WebKitPoint.h"
+#include "WebKitTransitionEvent.h"
+#include "WheelEvent.h"
+#include "XMLHttpRequest.h"
+#include "XMLHttpRequestException.h"
+#include "XMLHttpRequestProgressEvent.h"
+#include "XMLHttpRequestUpload.h"
+#include "XMLSerializer.h"
+#include "XPathEvaluator.h"
+#include "XPathException.h"
+#include "XPathExpression.h"
+#include "XPathNSResolver.h"
+#include "XPathResult.h"
+
+#if ENABLE(SVG)
+#include "SVGAngle.h"
+#include "SVGAnimatedPoints.h"
+#include "SVGColor.h"
+#include "SVGElement.h"
+#include "SVGElementInstance.h"
+#include "SVGElementInstanceList.h"
+#include "SVGException.h"
+#include "SVGLength.h"
+#include "SVGLengthList.h"
+#include "SVGNumberList.h"
+#include "SVGPaint.h"
+#include "SVGPathSeg.h"
+#include "SVGPathSegArc.h"
+#include "SVGPathSegClosePath.h"
+#include "SVGPathSegCurvetoCubic.h"
+#include "SVGPathSegCurvetoCubicSmooth.h"
+#include "SVGPathSegCurvetoQuadratic.h"
+#include "SVGPathSegCurvetoQuadraticSmooth.h"
+#include "SVGPathSegLineto.h"
+#include "SVGPathSegLinetoHorizontal.h"
+#include "SVGPathSegLinetoVertical.h"
+#include "SVGPathSegList.h"
+#include "SVGPathSegMoveto.h"
+#include "SVGPointList.h"
+#include "SVGPreserveAspectRatio.h"
+#include "SVGRenderingIntent.h"
+#include "SVGStringList.h"
+#include "SVGTransform.h"
+#include "SVGTransformList.h"
+#include "SVGUnitTypes.h"
+#include "SVGURIReference.h"
+#include "SVGZoomEvent.h"
+#include "V8SVGPODTypeWrapper.h"
+#endif // SVG
+
+#if ENABLE(WORKERS)
+#include "Worker.h"
+#include "WorkerContext.h"
+#include "WorkerLocation.h"
+#include "WorkerNavigator.h"
+#endif // WORKERS
+
+#if PLATFORM(ANDROID)
+#include "Coordinates.h"
+#include "Geolocation.h"
+#include "Geoposition.h"
+#include "PositionError.h"
+#include "PositionErrorCallback.h"
+#include "Touch.h"
+#include "TouchList.h"
+#include "TouchEvent.h"
+#include "VoidCallback.h"
+#endif
+
+namespace WebCore {
+
+// A helper class for undetectable document.all
+class UndetectableHTMLCollection : public HTMLCollection {
+};
+
+} // namespace WebCore
+
+#endif // DOMObjectsInclude_h
diff --git a/V8Binding/v8/JSDOMBinding.cpp b/V8Binding/v8/JSDOMBinding.cpp
new file mode 100644
index 0000000..c72a92b
--- /dev/null
+++ b/V8Binding/v8/JSDOMBinding.cpp
@@ -0,0 +1,52 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "JSDOMBinding.h"
+
+#include "Document.h"
+#include "Node.h"
+
+namespace WebCore {
+
+void updateDOMNodeDocument(Node* node, Document* oldDocument,
+ Document* newDocument)
+{
+ // We don't do anything here in V8 bindings
+}
+
+ScriptState* scriptStateFromNode(Node* node)
+{
+ // This should be never reached with V8 bindings (WebKit only uses it
+ // for non-JS bindings)
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/V8Binding/v8/JSDOMBinding.h b/V8Binding/v8/JSDOMBinding.h
new file mode 100644
index 0000000..8ed5602
--- /dev/null
+++ b/V8Binding/v8/JSDOMBinding.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Masquerade to pretend that we support JSC namespace and avoid unforking
+// This is not a reimplementation of the JSC namespace. It's just enough code
+// to avoid #ifdefs in WebKit code.
+
+#ifndef JSDOMBinding_h
+#define JSDOMBinding_h
+
+namespace WebCore {
+ class Node;
+ class Document;
+ class ScriptState;
+
+ void updateDOMNodeDocument(Node*, Document* oldDocument,
+ Document* newDocument);
+
+ ScriptState* scriptStateFromNode(Node*);
+
+}
+
+
+#endif // JSDOMBinding_h
diff --git a/V8Binding/v8/JSXPathNSResolver.cpp b/V8Binding/v8/JSXPathNSResolver.cpp
new file mode 100644
index 0000000..2fb2849
--- /dev/null
+++ b/V8Binding/v8/JSXPathNSResolver.cpp
@@ -0,0 +1,90 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "JSXPathNSResolver.h"
+
+#if ENABLE(XPATH)
+
+#include "v8_proxy.h"
+#include "v8_binding.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+JSXPathNSResolver::JSXPathNSResolver(v8::Handle<v8::Object> resolver)
+: m_resolver(resolver) {
+}
+
+JSXPathNSResolver::~JSXPathNSResolver() {
+}
+
+String JSXPathNSResolver::lookupNamespaceURI(const String& prefix) {
+ v8::Handle<v8::Function> lookupNamespaceURIFunc;
+ v8::Handle<v8::String> lookupNamespaceURIName = v8::String::New("lookupNamespaceURI");
+
+ // Check if the resolver has a function property named lookupNamespaceURI.
+ if (m_resolver->Has(lookupNamespaceURIName)) {
+ v8::Handle<v8::Value> lookupNamespaceURI = m_resolver->Get(lookupNamespaceURIName);
+ if (lookupNamespaceURI->IsFunction()) {
+ lookupNamespaceURIFunc = v8::Handle<v8::Function>::Cast(lookupNamespaceURI);
+ }
+ }
+
+ if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
+ Frame* frame = V8Proxy::retrieveActiveFrame();
+ log_info(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String());
+ return String();
+ }
+
+ // Catch exceptions from calling the namespace resolver.
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true); // Print exceptions to console.
+
+ const int argc = 1;
+ v8::Handle<v8::Value> argv[argc] = { v8String(prefix) };
+ v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty()
+ ? v8::Handle<v8::Function>::Cast(m_resolver)
+ : lookupNamespaceURIFunc;
+
+ V8Proxy* proxy = V8Proxy::retrieve();
+ v8::Handle<v8::Value> retval = proxy->CallFunction(function, m_resolver, argc, argv);
+
+ // Eat exceptions from namespace resolver and return an empty string. This
+ // will most likely cause NAMESPACE_ERR.
+ if (try_catch.HasCaught()) {
+ return String();
+ }
+
+ return ToWebCoreString(retval);
+}
+
+}
+
+#endif // ENABLE(XPATH)
diff --git a/V8Binding/v8/JSXPathNSResolver.h b/V8Binding/v8/JSXPathNSResolver.h
new file mode 100644
index 0000000..f0c340c
--- /dev/null
+++ b/V8Binding/v8/JSXPathNSResolver.h
@@ -0,0 +1,33 @@
+// 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 JSXPATHNSRESOLVER_H__
+#define JSXPATHNSRESOLVER_H__
+
+#if ENABLE(XPATH)
+
+#include <v8.h>
+#include <wtf/RefCounted.h>
+#include "XPathNSResolver.h"
+
+namespace WebCore {
+
+ class String;
+
+ class JSXPathNSResolver : public XPathNSResolver {
+ public:
+
+ JSXPathNSResolver(v8::Handle<v8::Object> resolver);
+ virtual ~JSXPathNSResolver();
+
+ virtual String lookupNamespaceURI(const String& prefix);
+
+ private:
+ v8::Handle<v8::Object> m_resolver; // Handle to resolver object.
+ };
+}
+
+#endif // ENABLE(XPATH)
+
+#endif // JSXPATHNSRESOLVER_H__
diff --git a/V8Binding/v8/NPV8Object.cpp b/V8Binding/v8/NPV8Object.cpp
new file mode 100644
index 0000000..defe6bf
--- /dev/null
+++ b/V8Binding/v8/NPV8Object.cpp
@@ -0,0 +1,504 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#define max max
+#define min min
+#include <v8.h>
+#include "NPV8Object.h"
+#if PLATFORM(CHROMIUM)
+#include "ChromiumBridge.h"
+#endif
+#include "Frame.h"
+#include "npruntime_priv.h"
+#include "PlatformString.h"
+#include "ScriptController.h"
+#include "v8_custom.h"
+#include "v8_helpers.h"
+#include "V8NPUtils.h"
+#include "v8_proxy.h"
+#include "DOMWindow.h"
+
+using WebCore::V8ClassIndex;
+using WebCore::V8Custom;
+using WebCore::V8Proxy;
+
+// FIXME(mbelshe): comments on why use malloc and free.
+static NPObject* AllocV8NPObject(NPP, NPClass*)
+{
+ return static_cast<NPObject*>(malloc(sizeof(V8NPObject)));
+}
+
+static void FreeV8NPObject(NPObject* npobj)
+{
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+#ifndef NDEBUG
+ V8Proxy::UnregisterGlobalHandle(object, object->v8Object);
+#endif
+ object->v8Object.Dispose();
+ free(object);
+}
+
+static v8::Handle<v8::Value>* listFromVariantArgs(const NPVariant* args,
+ uint32_t argCount,
+ NPObject *owner)
+{
+ v8::Handle<v8::Value>* argv = new v8::Handle<v8::Value>[argCount];
+ for (uint32_t index = 0; index < argCount; index++) {
+ const NPVariant *arg = &args[index];
+ argv[index] = convertNPVariantToV8Object(arg, owner);
+ }
+ return argv;
+}
+
+// Create an identifier (null terminated utf8 char*) from the NPIdentifier.
+static v8::Local<v8::String> NPIdentifierToV8Identifier(NPIdentifier name)
+{
+ PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(name);
+ if (identifier->isString)
+ return v8::String::New(static_cast<const char *>(identifier->value.string));
+
+ char buf[32];
+ sprintf(buf, "%d", identifier->value.number);
+ return v8::String::New(buf);
+}
+
+static NPClass V8NPObjectClass = { NP_CLASS_STRUCT_VERSION,
+ AllocV8NPObject,
+ FreeV8NPObject,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+// NPAPI's npruntime functions
+NPClass* npScriptObjectClass = &V8NPObjectClass;
+
+NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, WebCore::DOMWindow* root)
+{
+ // Check to see if this object is already wrapped.
+ if (object->InternalFieldCount() == V8Custom::kNPObjectInternalFieldCount &&
+ object->GetInternalField(V8Custom::kDOMWrapperTypeIndex)->IsNumber() &&
+ object->GetInternalField(V8Custom::kDOMWrapperTypeIndex)->Uint32Value() == V8ClassIndex::NPOBJECT) {
+
+ NPObject* rv = V8Proxy::ToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, object);
+ NPN_RetainObject(rv);
+ return rv;
+ }
+
+ V8NPObject* obj = reinterpret_cast<V8NPObject*>(NPN_CreateObject(npp, &V8NPObjectClass));
+ obj->v8Object = v8::Persistent<v8::Object>::New(object);
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(WebCore::NPOBJECT, obj, obj->v8Object);
+#endif
+ obj->rootObject = root;
+ return reinterpret_cast<NPObject*>(obj);
+}
+
+bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,
+ const NPVariant *args, uint32_t argCount, NPVariant *result)
+{
+ if (!npobj)
+ return false;
+
+ if (npobj->_class == npScriptObjectClass) {
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+
+ PrivateIdentifier *identifier = static_cast<PrivateIdentifier*>(methodName);
+ if (!identifier->isString)
+ return false;
+
+ v8::HandleScope handleScope;
+ // FIXME: should use the plugin's owner frame as the security context
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+
+ v8::Context::Scope scope(context);
+
+ // Special case the "eval" method.
+ if (methodName == NPN_GetStringIdentifier("eval")) {
+ if (argCount != 1)
+ return false;
+ if (args[0].type != NPVariantType_String)
+ return false;
+ return NPN_Evaluate(npp, npobj, const_cast<NPString*>(&args[0].value.stringValue), result);
+ }
+
+ v8::Handle<v8::Value> funcObj = object->v8Object->Get(v8::String::New(identifier->value.string));
+ if (funcObj.IsEmpty() || funcObj->IsNull()) {
+ NULL_TO_NPVARIANT(*result);
+ return false;
+ }
+ if (funcObj->IsUndefined()) {
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ }
+
+ WebCore::V8Proxy* proxy = GetV8Proxy(npobj);
+ ASSERT(proxy); // must not be null
+
+ // FIXME: fix variable naming
+ // Call the function object
+ v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(funcObj);
+ // Create list of args to pass to v8
+ v8::Handle<v8::Value>* argv = listFromVariantArgs(args, argCount, npobj);
+ v8::Local<v8::Value> resultObj = proxy->CallFunction(func, object->v8Object, argCount, argv);
+ delete[] argv;
+
+ // If we had an error, return false. The spec is a little unclear here, but
+ // says "Returns true if the method was successfully invoked". If we get an
+ // error return value, was that successfully invoked?
+ if (resultObj.IsEmpty())
+ return false;
+
+ // Convert the result back to an NPVariant
+ convertV8ObjectToNPVariant(resultObj, npobj, result);
+ return true;
+ }
+
+ if (npobj->_class->invoke)
+ return npobj->_class->invoke(npobj, methodName, args, argCount, result);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+}
+
+// FIXME: Fix it same as NPN_Invoke (HandleScope and such)
+bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,
+ uint32_t argCount, NPVariant *result)
+{
+ if (!npobj)
+ return false;
+
+ if (npobj->_class == npScriptObjectClass) {
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+
+ VOID_TO_NPVARIANT(*result);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+
+ v8::Context::Scope scope(context);
+
+ // Lookup the function object
+ v8::Handle<v8::Object> funcObj(object->v8Object);
+ if (!funcObj->IsFunction())
+ return false;
+
+ // Call the function object
+ v8::Local<v8::Value> resultObj;
+ v8::Handle<v8::Function> func(v8::Function::Cast(*funcObj));
+ if (!func->IsNull()) {
+ WebCore::V8Proxy* proxy = GetV8Proxy(npobj);
+ ASSERT(proxy);
+
+ // Create list of args to pass to v8
+ v8::Handle<v8::Value>* argv = listFromVariantArgs(args, argCount, npobj);
+ resultObj = proxy->CallFunction(func, funcObj, argCount, argv);
+ delete[] argv;
+ }
+
+ // If we had an error, return false. The spec is a little unclear here, but
+ // says "Returns true if the method was successfully invoked". If we get an
+ // error return value, was that successfully invoked?
+ if (resultObj.IsEmpty())
+ return false;
+
+ // Convert the result back to an NPVariant.
+ convertV8ObjectToNPVariant(resultObj, npobj, result);
+ return true;
+ }
+
+ if (npobj->_class->invokeDefault)
+ return npobj->_class->invokeDefault(npobj, args, argCount, result);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+}
+
+#if PLATFORM(ANDROID)
+static
+#endif
+bool NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npobj, NPString* npscript, NPVariant *result)
+{
+ VOID_TO_NPVARIANT(*result);
+ if (!npobj)
+ return false;
+
+ if (npobj->_class != npScriptObjectClass)
+ return false;
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+
+ WebCore::V8Proxy* proxy = GetV8Proxy(npobj);
+ ASSERT(proxy);
+
+ v8::Context::Scope scope(context);
+
+ WebCore::String filename;
+ if (!popupsAllowed)
+ filename = "npscript";
+
+ // Convert UTF-8 stream to WebCore::String.
+ WebCore::String script = WebCore::String::fromUTF8(npscript->UTF8Characters, npscript->UTF8Length);
+ v8::Local<v8::Value> v8result = proxy->evaluate(WebCore::ScriptSourceCode(script, WebCore::KURL(filename)), 0);
+
+ // If we had an error, return false.
+ if (v8result.IsEmpty())
+ return false;
+
+ convertV8ObjectToNPVariant(v8result, npobj, result);
+ return true;
+}
+
+bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *npscript, NPVariant *result)
+{
+#if PLATFORM(CHROMIUM)
+ bool popupsAllowed = WebCore::ChromiumBridge::popupsAllowed(npp);
+#else
+ // TODO(fqian): create an Android bridge
+ bool popupsAllowed = false;
+#endif
+ return NPN_EvaluateHelper(npp, popupsAllowed, npobj, npscript, result);
+}
+
+bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, NPVariant *result)
+{
+ if (!npobj)
+ return false;
+
+ if (npobj->_class == npScriptObjectClass) {
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ v8::Local<v8::Value> v8result = obj->Get(NPIdentifierToV8Identifier(propertyName));
+
+ convertV8ObjectToNPVariant(v8result, npobj, result);
+ return true;
+ }
+
+ if (npobj->_class->hasProperty && npobj->_class->getProperty) {
+ if (npobj->_class->hasProperty(npobj, propertyName))
+ return npobj->_class->getProperty(npobj, propertyName, result);
+ }
+
+ VOID_TO_NPVARIANT(*result);
+ return false;
+}
+
+bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, const NPVariant *value)
+{
+ if (!npobj)
+ return false;
+
+ if (npobj->_class == npScriptObjectClass) {
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ obj->Set(NPIdentifierToV8Identifier(propertyName),
+ convertNPVariantToV8Object(value, object->rootObject->frame()->script()->windowScriptNPObject()));
+ return true;
+ }
+
+ if (npobj->_class->setProperty)
+ return npobj->_class->setProperty(npobj, propertyName, value);
+
+ return false;
+}
+
+bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName)
+{
+ if (!npobj)
+ return false;
+ if (npobj->_class != npScriptObjectClass)
+ return false;
+
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ // FIXME(mbelshe) - verify that setting to undefined is right.
+ obj->Set(NPIdentifierToV8Identifier(propertyName), v8::Undefined());
+ return true;
+}
+
+bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName)
+{
+ if (!npobj)
+ return false;
+
+ if (npobj->_class == npScriptObjectClass) {
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ return obj->Has(NPIdentifierToV8Identifier(propertyName));
+ }
+
+ if (npobj->_class->hasProperty)
+ return npobj->_class->hasProperty(npobj, propertyName);
+ return false;
+}
+
+bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName)
+{
+ if (!npobj)
+ return false;
+
+ if (npobj->_class == npScriptObjectClass) {
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ v8::Handle<v8::Value> prop = obj->Get(NPIdentifierToV8Identifier(methodName));
+ return prop->IsFunction();
+ }
+
+ if (npobj->_class->hasMethod)
+ return npobj->_class->hasMethod(npobj, methodName);
+ return false;
+}
+
+void NPN_SetException(NPObject *npobj, const NPUTF8 *message)
+{
+ if (npobj->_class != npScriptObjectClass)
+ return;
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(0, npobj);
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+ V8Proxy::ThrowError(V8Proxy::GENERAL_ERROR, message);
+}
+
+bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count)
+{
+ if (!npobj)
+ return false;
+
+ if (npobj->_class == npScriptObjectClass) {
+ V8NPObject *object = reinterpret_cast<V8NPObject*>(npobj);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = getV8Context(npp, npobj);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+
+ // FIXME(fqian): http://b/issue?id=1210340: Use a v8::Object::Keys() method
+ // when it exists, instead of evaluating javascript.
+
+ // FIXME(mpcomplete): figure out how to cache this helper function.
+ // Run a helper function that collects the properties on the object into
+ // an array.
+ const char enumeratorCode[] =
+ "(function (obj) {"
+ " var props = [];"
+ " for (var prop in obj) {"
+ " props[props.length] = prop;"
+ " }"
+ " return props;"
+ "});";
+ v8::Handle<v8::String> source = v8::String::New(enumeratorCode);
+ v8::Handle<v8::Script> script = v8::Script::Compile(source, 0);
+ v8::Handle<v8::Value> enumeratorObj = script->Run();
+ v8::Handle<v8::Function> enumerator = v8::Handle<v8::Function>::Cast(enumeratorObj);
+ v8::Handle<v8::Value> argv[] = { obj };
+ v8::Local<v8::Value> propsObj = enumerator->Call(v8::Handle<v8::Object>::Cast(enumeratorObj), 1, argv);
+ if (propsObj.IsEmpty())
+ return false;
+
+ // Convert the results into an array of NPIdentifiers.
+ v8::Handle<v8::Array> props = v8::Handle<v8::Array>::Cast(propsObj);
+ *count = props->Length();
+ *identifier = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier*) * *count));
+ for (uint32_t i = 0; i < *count; ++i) {
+ v8::Local<v8::Value> name = props->Get(v8::Integer::New(i));
+ (*identifier)[i] = getStringIdentifier(v8::Local<v8::String>::Cast(name));
+ }
+ return true;
+ }
+
+ if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npobj->_class) && npobj->_class->enumerate)
+ return npobj->_class->enumerate(npobj, identifier, count);
+
+ return false;
+}
+
+bool NPN_Construct(NPP npp, NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+ if (!npobj)
+ return false;
+
+ // FIXME(estade): implement this case.
+ if (npobj->_class == npScriptObjectClass) {
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ }
+
+ if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(npobj->_class) && npobj->_class->construct)
+ return npobj->_class->construct(npobj, args, argCount, result);
+
+ return false;
+}
diff --git a/V8Binding/v8/NPV8Object.h b/V8Binding/v8/NPV8Object.h
new file mode 100644
index 0000000..1b9713e
--- /dev/null
+++ b/V8Binding/v8/NPV8Object.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2006-2009 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 np_v8object_h
+#define np_v8object_h
+
+#if PLATFORM(CHROMIUM)
+#include "bindings/npruntime.h"
+#else
+#include "bridge/npruntime.h" // use WebCore version
+#endif
+
+#include <v8.h>
+
+namespace WebCore {
+ class DOMWindow;
+}
+
+extern NPClass* npScriptObjectClass;
+
+// A V8NPObject is a NPObject which carries additional V8-specific
+// information. It is allocated and deallocated by AllocV8NPObject()
+// and FreeV8NPObject() methods.
+struct V8NPObject {
+ NPObject object;
+ v8::Persistent<v8::Object> v8Object;
+ WebCore::DOMWindow* rootObject;
+};
+
+struct PrivateIdentifier {
+ union {
+ const NPUTF8* string;
+ int32_t number;
+ } value;
+ bool isString;
+};
+
+NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object>, WebCore::DOMWindow*);
+
+#endif // np_v8object_h
diff --git a/V8Binding/v8/RGBColor.cpp b/V8Binding/v8/RGBColor.cpp
new file mode 100644
index 0000000..4a37ea6
--- /dev/null
+++ b/V8Binding/v8/RGBColor.cpp
@@ -0,0 +1,50 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "RGBColor.h"
+
+namespace WebCore {
+
+PassRefPtr<CSSPrimitiveValue> RGBColor::red() {
+ unsigned int value = (m_rgbcolor >> 16) & 0xFF;
+ return CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
+}
+
+PassRefPtr<CSSPrimitiveValue> RGBColor::green() {
+ unsigned int value = (m_rgbcolor >> 8) & 0xFF;
+ return CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
+}
+
+PassRefPtr<CSSPrimitiveValue> RGBColor::blue() {
+ unsigned int value = m_rgbcolor & 0xFF;
+ return CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
+}
+
+} // namespace WebCore
+
diff --git a/V8Binding/v8/RGBColor.h b/V8Binding/v8/RGBColor.h
new file mode 100644
index 0000000..afc0500
--- /dev/null
+++ b/V8Binding/v8/RGBColor.h
@@ -0,0 +1,28 @@
+// 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 RGBColor_h
+#define RGBColor_h
+
+#include "config.h"
+#include "CSSPrimitiveValue.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class RGBColor : public RefCounted<RGBColor> {
+ public:
+ RGBColor(unsigned rgbcolor) : m_rgbcolor(rgbcolor) { }
+
+ PassRefPtr<CSSPrimitiveValue> red();
+ PassRefPtr<CSSPrimitiveValue> green();
+ PassRefPtr<CSSPrimitiveValue> blue();
+
+ private:
+ unsigned m_rgbcolor;
+};
+
+} // namespace WebCore
+
+#endif // RGBColor_h
diff --git a/V8Binding/v8/ScriptController.cpp b/V8Binding/v8/ScriptController.cpp
new file mode 100644
index 0000000..83dc52c
--- /dev/null
+++ b/V8Binding/v8/ScriptController.cpp
@@ -0,0 +1,446 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "ScriptController.h"
+
+#if PLATFORM(CHROMIUM)
+#include "ChromiumBridge.h"
+#endif
+
+#include "CString.h"
+#include "Document.h"
+#include "DOMWindow.h"
+#include "Event.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "Frame.h"
+#include "Node.h"
+#include "NotImplemented.h"
+#include "npruntime_priv.h"
+#include "NPV8Object.h"
+#include "ScriptSourceCode.h"
+#include "Widget.h"
+
+#include "v8_proxy.h"
+#include "v8_binding.h"
+#include "V8NPObject.h"
+
+NPRuntimeFunctions npruntime_functions = {
+ NPN_GetStringIdentifier,
+ NPN_GetStringIdentifiers,
+ NPN_GetIntIdentifier,
+ NPN_IdentifierIsString,
+ NPN_UTF8FromIdentifier,
+ NPN_IntFromIdentifier,
+ NPN_CreateObject,
+ NPN_RetainObject,
+ NPN_ReleaseObject,
+ NPN_Invoke,
+ NPN_InvokeDefault,
+ NPN_Evaluate,
+ NPN_GetProperty,
+ NPN_SetProperty,
+ NPN_RemoveProperty,
+ NPN_HasProperty,
+ NPN_HasMethod,
+ NPN_ReleaseVariantValue,
+ NPN_SetException
+};
+
+
+namespace WebCore {
+
+void ScriptController::setFlags(const char* str, int length)
+{
+ v8::V8::SetFlagsFromString(str, length);
+}
+
+Frame* ScriptController::retrieveActiveFrame()
+{
+ return V8Proxy::retrieveActiveFrame();
+}
+
+bool ScriptController::isSafeScript(Frame* target)
+{
+ return V8Proxy::CanAccessFrame(target, true);
+}
+
+void ScriptController::gcProtectJSWrapper(void* dom_object)
+{
+ V8Proxy::GCProtect(dom_object);
+}
+
+void ScriptController::gcUnprotectJSWrapper(void* dom_object)
+{
+ V8Proxy::GCUnprotect(dom_object);
+}
+
+ScriptController::ScriptController(Frame* frame)
+ : m_frame(frame)
+ , m_sourceURL(0)
+ , m_processingTimerCallback(false)
+ , m_paused(false)
+ , m_proxy(new V8Proxy(frame))
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ , m_windowScriptNPObject(0)
+#endif
+{
+}
+
+ScriptController::~ScriptController()
+{
+}
+
+void ScriptController::clearScriptObjects()
+{
+ PluginObjectMap::iterator it = m_pluginObjects.begin();
+ for (; it != m_pluginObjects.end(); ++it) {
+ _NPN_UnregisterObject(it->second);
+ NPN_ReleaseObject(it->second);
+ }
+ m_pluginObjects.clear();
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ if (m_windowScriptNPObject) {
+ // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window
+ // script object properly.
+ // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point.
+ _NPN_DeallocateObject(m_windowScriptNPObject);
+ m_windowScriptNPObject = 0;
+ }
+#endif
+}
+
+void ScriptController::updateSecurityOrigin()
+{
+ m_proxy->updateSecurityOrigin();
+}
+
+void ScriptController::updatePlatformScriptObjects()
+{
+ notImplemented();
+}
+
+// Disconnect the proxy from its owner frame;
+void ScriptController::disconnectFrame()
+{
+ m_proxy->disconnectFrame();
+}
+
+bool ScriptController::processingUserGesture() const
+{
+ Frame* active_frame = V8Proxy::retrieveActiveFrame();
+ // No script is running, must be run by users.
+ if (!active_frame)
+ return true;
+
+ V8Proxy* active_proxy = active_frame->script()->proxy();
+
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(active_frame);
+ // TODO(fqian): find all cases context can be empty:
+ // 1) JS is disabled;
+ // 2) page is NULL;
+ if (context.IsEmpty())
+ return true;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> global = context->Global();
+ v8::Handle<v8::Value> jsevent = global->Get(v8::String::NewSymbol("event"));
+ Event* event = V8Proxy::ToNativeEvent(jsevent);
+
+ // Based on code from kjs_bindings.cpp.
+ // Note: This is more liberal than Firefox's implementation.
+ if (event) {
+ const AtomicString& type = event->type();
+ bool event_ok =
+ // mouse events
+ type == eventNames().clickEvent ||
+ type == eventNames().mousedownEvent ||
+ type == eventNames().mouseupEvent ||
+ type == eventNames().dblclickEvent ||
+ // keyboard events
+ type == eventNames().keydownEvent ||
+ type == eventNames().keypressEvent ||
+ type == eventNames().keyupEvent ||
+ // other accepted events
+ type == eventNames().selectEvent ||
+ type == eventNames().changeEvent ||
+ type == eventNames().focusEvent ||
+ type == eventNames().blurEvent ||
+ type == eventNames().submitEvent;
+
+ if (event_ok)
+ return true;
+ } else if (active_proxy->inlineCode() && !active_proxy->timerCallback())
+ // This is the <a href="javascript:window.open('...')> case -> we let it
+ // through
+ return true;
+
+ // This is the <script>window.open(...)</script> case or a timer callback ->
+ // block it
+ return false;
+}
+
+void ScriptController::evaluateInNewContext(
+ const Vector<ScriptSourceCode>& sources) {
+ m_proxy->evaluateInNewContext(sources);
+}
+
+// Evaluate a script file in the environment of this proxy.
+ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
+{
+ v8::HandleScope hs;
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame());
+ if (context.IsEmpty())
+ return ScriptValue();
+
+ v8::Context::Scope scope(context);
+ v8::Local<v8::Value> obj = m_proxy->evaluate(sourceCode, NULL);
+
+ if (obj.IsEmpty() || obj->IsUndefined())
+ return ScriptValue();
+
+ return ScriptValue(obj);
+}
+
+void ScriptController::disposeJSResult(v8::Persistent<v8::Value> result)
+{
+ result.Dispose();
+ result.Clear();
+}
+
+PassRefPtr<EventListener> ScriptController::createInlineEventListener(
+ const String& functionName, const String& code, Node* node)
+{
+ return m_proxy->createInlineEventListener(functionName, code, node);
+}
+
+#if ENABLE(SVG)
+PassRefPtr<EventListener> ScriptController::createSVGEventHandler(
+ const String& functionName, const String& code, Node* node)
+{
+ return m_proxy->createSVGEventHandler(functionName, code, node);
+}
+#endif
+
+void ScriptController::setEventHandlerLineno(int lineno)
+{
+ m_proxy->setEventHandlerLineno(lineno);
+}
+
+void ScriptController::finishedWithEvent(Event* evt)
+{
+ m_proxy->finishedWithEvent(evt);
+}
+
+// Create a V8 object with an interceptor of NPObjectPropertyGetter
+void ScriptController::BindToWindowObject(Frame* frame, const String& key, NPObject* object)
+{
+ v8::HandleScope handle_scope;
+
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(frame);
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> value = CreateV8ObjectForNPObject(object, NULL);
+
+ // Attach to the global object
+ v8::Handle<v8::Object> global = context->Global();
+ global->Set(v8String(key), value);
+}
+
+void ScriptController::collectGarbage()
+{
+ v8::HandleScope hs;
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame());
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+
+ m_proxy->evaluate(ScriptSourceCode("if (window.gc) void(gc());"), NULL);
+}
+
+NPRuntimeFunctions* ScriptController::functions()
+{
+ return &npruntime_functions;
+}
+
+
+bool ScriptController::haveInterpreter() const
+{
+ return m_proxy->ContextInitialized();
+}
+
+bool ScriptController::isEnabled() const
+{
+ return m_proxy->isEnabled();
+}
+
+PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget)
+{
+ ASSERT(widget != 0);
+
+ if (widget->isFrameView())
+ return 0;
+
+#if PLATFORM(CHROMIUM)
+ NPObject* npObject = ChromiumBridge::pluginScriptableObject(widget);
+#else
+ NPObject* npObject = 0; // TODO(fqian): fix this
+#endif
+ if (!npObject)
+ return 0;
+ // Frame Memory Management for NPObjects
+ // -------------------------------------
+ // NPObjects are treated differently than other objects wrapped by JS.
+ // NPObjects can be created either by the browser (e.g. the main
+ // window object) or by the plugin (the main plugin object
+ // for a HTMLEmbedElement). Further,
+ // unlike most DOM Objects, the frame is especially careful to ensure
+ // NPObjects terminate at frame teardown because if a plugin leaks a
+ // reference, it could leak its objects (or the browser's objects).
+ //
+ // The Frame maintains a list of plugin objects (m_pluginObjects)
+ // which it can use to quickly find the wrapped embed object.
+ //
+ // Inside the NPRuntime, we've added a few methods for registering
+ // wrapped NPObjects. The purpose of the registration is because
+ // javascript garbage collection is non-deterministic, yet we need to
+ // be able to tear down the plugin objects immediately. When an object
+ // is registered, javascript can use it. When the object is destroyed,
+ // or when the object's "owning" object is destroyed, the object will
+ // be un-registered, and the javascript engine must not use it.
+ //
+ // Inside the javascript engine, the engine can keep a reference to the
+ // NPObject as part of its wrapper. However, before accessing the object
+ // it must consult the NPN_Registry.
+
+ v8::Local<v8::Object> wrapper = CreateV8ObjectForNPObject(npObject, NULL);
+
+ // Track the plugin object. We've been given a reference to the object.
+ m_pluginObjects.set(widget, npObject);
+
+ return V8ScriptInstance::create(wrapper);
+}
+
+void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle)
+{
+ PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle);
+ if (it == m_pluginObjects.end())
+ return;
+ _NPN_UnregisterObject(it->second);
+ NPN_ReleaseObject(it->second);
+ m_pluginObjects.remove(it);
+}
+
+static NPObject* createNoScriptObject()
+{
+ notImplemented();
+ return 0;
+}
+
+static NPObject* createScriptObject(Frame* frame)
+{
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(frame);
+ if (context.IsEmpty())
+ return createNoScriptObject();
+
+ v8::Context::Scope scope(context);
+ DOMWindow* window = frame->domWindow();
+ v8::Handle<v8::Value> global = V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, window);
+ ASSERT(global->IsObject());
+ return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(global), window);
+}
+
+NPObject* ScriptController::windowScriptNPObject()
+{
+ if (m_windowScriptNPObject)
+ return m_windowScriptNPObject;
+
+ if (isEnabled()) {
+ // JavaScript is enabled, so there is a JavaScript window object.
+ // Return an NPObject bound to the window object.
+ m_windowScriptNPObject = createScriptObject(m_frame);
+ _NPN_RegisterObject(m_windowScriptNPObject, NULL);
+ } else {
+ // JavaScript is not enabled, so we cannot bind the NPObject to the
+ // JavaScript window object. Instead, we create an NPObject of a
+ // different class, one which is not bound to a JavaScript object.
+ m_windowScriptNPObject = createNoScriptObject();
+ }
+ return m_windowScriptNPObject;
+}
+
+NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin)
+{
+ // Can't create NPObjects when JavaScript is disabled
+ if (!isEnabled())
+ return createNoScriptObject();
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame);
+ if (context.IsEmpty())
+ return createNoScriptObject();
+ v8::Context::Scope scope(context);
+
+ DOMWindow* window = m_frame->domWindow();
+ v8::Handle<v8::Value> v8plugin = V8Proxy::ToV8Object(V8ClassIndex::HTMLEMBEDELEMENT, plugin);
+ if (!v8plugin->IsObject())
+ return createNoScriptObject();
+
+ return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(v8plugin), window);
+}
+
+
+void ScriptController::clearWindowShell()
+{
+ // V8 binding expects ScriptController::clearWindowShell only be called
+ // when a frame is loading a new page. V8Proxy::clearForNavigation
+ // creates a new context for the new page.
+ m_proxy->clearForNavigation();
+}
+
+void ScriptController::attachDebugger(void*)
+{
+ notImplemented();
+}
+
+void ScriptController::updateDocument()
+{
+ m_proxy->updateDocument();
+}
+
+} // namespace WebCpre
diff --git a/V8Binding/v8/ScriptController.h b/V8Binding/v8/ScriptController.h
new file mode 100644
index 0000000..d26dbcc
--- /dev/null
+++ b/V8Binding/v8/ScriptController.h
@@ -0,0 +1,271 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// An interface to abstract implementation differences
+// for various Javascript engines.
+
+#ifndef ScriptController_h
+#define ScriptController_h
+
+#include "HashMap.h"
+#include "MessagePort.h"
+#include "ScriptInstance.h"
+#include "ScriptValue.h"
+#include "SecurityOrigin.h"
+
+#if PLATFORM(CHROMIUM)
+#include "bindings/npruntime.h"
+#else
+#include "bridge/npruntime.h" // use WebCore version
+#endif
+
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+#include "v8.h"
+#include "v8_proxy.h"
+
+// JavaScript implementations which expose NPObject will need to implement
+// these methods.
+typedef void (*NPN_ReleaseVariantValueProcPtr) (NPVariant *variant);
+
+typedef NPIdentifier(*NPN_GetStringIdentifierProcPtr) (const NPUTF8 *name);
+typedef void (*NPN_GetStringIdentifiersProcPtr) (const NPUTF8 **names,
+ int32_t nameCount,
+ NPIdentifier *identifiers);
+typedef NPIdentifier(*NPN_GetIntIdentifierProcPtr) (int32_t intid);
+typedef int32_t (*NPN_IntFromIdentifierProcPtr) (NPIdentifier identifier);
+typedef bool (*NPN_IdentifierIsStringProcPtr) (NPIdentifier identifier);
+typedef NPUTF8 * (*NPN_UTF8FromIdentifierProcPtr) (NPIdentifier identifier);
+
+typedef NPObject* (*NPN_CreateObjectProcPtr) (NPP,
+ NPClass *aClass);
+typedef NPObject* (*NPN_RetainObjectProcPtr) (NPObject *obj);
+typedef void (*NPN_ReleaseObjectProcPtr) (NPObject *obj);
+typedef bool (*NPN_InvokeProcPtr) (NPP npp,
+ NPObject *obj,
+ NPIdentifier methodName,
+ const NPVariant *args,
+ unsigned argCount,
+ NPVariant *result);
+typedef bool (*NPN_InvokeDefaultProcPtr) (NPP npp,
+ NPObject *obj,
+ const NPVariant *args,
+ unsigned argCount,
+ NPVariant *result);
+typedef bool (*NPN_EvaluateProcPtr) (NPP npp,
+ NPObject *obj,
+ NPString *script,
+ NPVariant *result);
+typedef bool (*NPN_GetPropertyProcPtr) (NPP npp,
+ NPObject *obj,
+ NPIdentifier propertyName,
+ NPVariant *result);
+typedef bool (*NPN_SetPropertyProcPtr) (NPP npp,
+ NPObject *obj,
+ NPIdentifier propertyName,
+ const NPVariant *value);
+typedef bool (*NPN_HasPropertyProcPtr) (NPP,
+ NPObject *npobj,
+ NPIdentifier propertyName);
+typedef bool (*NPN_HasMethodProcPtr) (NPP npp,
+ NPObject *npobj,
+ NPIdentifier methodName);
+typedef bool (*NPN_RemovePropertyProcPtr) (NPP npp,
+ NPObject *obj,
+ NPIdentifier propertyName);
+typedef void (*NPN_SetExceptionProcPtr) (NPObject *obj,
+ const NPUTF8 *message);
+
+typedef struct _NPRuntimeFunctions {
+ NPN_GetStringIdentifierProcPtr getStringIdentifier;
+ NPN_GetStringIdentifiersProcPtr getStringIdentifiers;
+ NPN_GetIntIdentifierProcPtr getIntIdentifier;
+ NPN_IdentifierIsStringProcPtr identifierIsString;
+ NPN_UTF8FromIdentifierProcPtr utf8FromIdentifier;
+ NPN_IntFromIdentifierProcPtr intFromIdentifier;
+ NPN_CreateObjectProcPtr createObject;
+ NPN_RetainObjectProcPtr retainObject;
+ NPN_ReleaseObjectProcPtr releaseObject;
+ NPN_InvokeProcPtr invoke;
+ NPN_InvokeDefaultProcPtr invokeDefault;
+ NPN_EvaluateProcPtr evaluate;
+ NPN_GetPropertyProcPtr getProperty;
+ NPN_SetPropertyProcPtr setProperty;
+ NPN_RemovePropertyProcPtr removeProperty;
+ NPN_HasPropertyProcPtr hasProperty;
+ NPN_HasMethodProcPtr hasMethod;
+ NPN_ReleaseVariantValueProcPtr releaseVariantValue;
+ NPN_SetExceptionProcPtr setException;
+} NPRuntimeFunctions;
+
+namespace WebCore {
+class Document;
+class EventListener;
+class Event;
+class Frame;
+class HTMLPlugInElement;
+class Node;
+class ScriptSourceCode;
+class String;
+class Widget;
+
+typedef v8::Local<v8::Object> JSInstance;
+typedef v8::Local<v8::Object> JSInstanceHandle;
+typedef v8::Persistent<v8::Object> JSPersistentInstance;
+typedef v8::Local<v8::Value> JSException;
+typedef v8::Persistent<v8::Value> JSResult;
+
+class ScriptController {
+public:
+ ScriptController(Frame*);
+ ~ScriptController();
+
+ // TODO(eseidel): V8Proxy should either be folded into ScriptController
+ // or this accessor should be made JSProxy*
+ V8Proxy* proxy() { return m_proxy.get(); }
+
+ // Evaluate a script file in the environment of this proxy.
+ // If succeeded, 'succ' is set to true and result is returned
+ // as a string.
+ ScriptValue evaluate(const ScriptSourceCode&);
+
+ // Executes JavaScript in a new context associated with the web frame. The
+ // script gets its own global scope and its own prototypes for intrinsic
+ // JavaScript objects (String, Array, and so-on). It shares the wrappers for
+ // all DOM nodes and DOM constructors.
+ void evaluateInNewContext(const Vector<ScriptSourceCode>& sources);
+
+ // JSC has a WindowShell object, but for V8, the ScriptController
+ // is the WindowShell.
+ bool haveWindowShell() const { return true; }
+
+ // Masquerade 'this' as the windowShell.
+ // This is a bit of a hack, but provides reasonable compatibility
+ // with what JSC does as well.
+ ScriptController* windowShell() { return this; }
+
+ void disposeJSResult(JSResult result);
+ void collectGarbage();
+
+ PassRefPtr<EventListener> createInlineEventListener(const String& functionName, const String& code, Node*);
+#if ENABLE(SVG)
+ PassRefPtr<EventListener> createSVGEventHandler(const String& functionName, const String& code, Node*);
+#endif
+
+ // Creates a property of the global object of a frame.
+ void BindToWindowObject(Frame*, const String& key, NPObject*);
+
+ NPRuntimeFunctions* functions();
+
+ PassScriptInstance createScriptInstanceForWidget(Widget*);
+
+ void disconnectFrame();
+
+ // Check if the javascript engine has been initialized.
+ bool haveInterpreter() const;
+
+ bool isEnabled() const;
+
+ // TODO(eseidel): void* is a compile hack
+ void attachDebugger(void*);
+
+ // Create a NPObject wrapper for a JSObject
+ // NPObject *WrapScriptObject(NPP pluginId, JSObject* objectToWrap,
+ // JSRootObject* originRootObject,
+ // JSRootObject* rootObject);
+
+ // --- Static methods assume we are running VM in single thread, ---
+ // --- and there is only one VM instance. ---
+
+ // Returns the frame of the calling code is in.
+ // Not necessary the frame of this proxy.
+ // For example, JS code in frame A calls windowB.open(...).
+ // Window::open method has the frame pointer of B, but
+ // the execution context is in frame A, so it needs
+ // frame A's loader to complete URL.
+ static Frame* retrieveActiveFrame();
+
+ // Check whether it is safe to access a frame in another domain.
+ static bool isSafeScript(Frame* target);
+
+ // Pass command-line flags to the JS engine
+ static void setFlags(const char* str, int length);
+
+ // Protect and unprotect the JS wrapper from garbage collected.
+ static void gcProtectJSWrapper(void* object);
+ static void gcUnprotectJSWrapper(void* object);
+
+ void finishedWithEvent(Event*);
+ void setEventHandlerLineno(int lineno);
+
+ void setProcessingTimerCallback(bool b) { m_processingTimerCallback = b; }
+ bool processingUserGesture() const;
+
+ void setPaused(bool b) { m_paused = b; }
+ bool isPaused() const { return m_paused; }
+
+ const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script
+
+ void clearWindowShell();
+ void updateDocument();
+
+ void updateSecurityOrigin();
+ void clearScriptObjects();
+ void updatePlatformScriptObjects();
+ void cleanupScriptObjectsForPlugin(void*);
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*);
+ NPObject* windowScriptNPObject();
+#endif
+
+private:
+ Frame* m_frame;
+ const String* m_sourceURL;
+
+ bool m_processingTimerCallback;
+ bool m_paused;
+
+ OwnPtr<V8Proxy> m_proxy;
+ typedef HashMap<void*, NPObject*> PluginObjectMap;
+
+ // A mapping between Widgets and their corresponding script object.
+ // This list is used so that when the plugin dies, we can immediately
+ // invalidate all sub-objects which are associated with that plugin.
+ // The frame keeps a NPObject reference for each item on the list.
+ PluginObjectMap m_pluginObjects;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ NPObject* m_windowScriptNPObject;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // ScriptController_h
diff --git a/V8Binding/v8/UndetectableHTMLCollection.idl b/V8Binding/v8/UndetectableHTMLCollection.idl
new file mode 100644
index 0000000..bcb2aee
--- /dev/null
+++ b/V8Binding/v8/UndetectableHTMLCollection.idl
@@ -0,0 +1,14 @@
+// Copyright (c) 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.
+
+module html {
+
+ // This interface is used for undetectable HTMLCollections.
+ // An undetectable HTMLCollection behaves like an HTMLCollection
+ // when used, but the 'typeof' operator returns undefined and
+ // ToBoolean returns false.
+ interface UndetectableHTMLCollection : HTMLCollection {
+ };
+
+}
diff --git a/V8Binding/v8/V8CanvasPixelArrayCustom.cpp b/V8Binding/v8/V8CanvasPixelArrayCustom.cpp
new file mode 100644
index 0000000..d5441a1
--- /dev/null
+++ b/V8Binding/v8/V8CanvasPixelArrayCustom.cpp
@@ -0,0 +1,77 @@
+// Copyright (c) 2009, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_proxy.h"
+
+#include "CanvasPixelArray.h"
+
+namespace WebCore {
+
+// Get the specified value from the pixel buffer and return it wrapped as a
+// JavaScript Number object to V8. Accesses outside the valid pixel buffer
+// range return "undefined".
+INDEXED_PROPERTY_GETTER(CanvasPixelArray) {
+ INC_STATS("DOM.CanvasPixelArray.IndexedPropertyGetter");
+ CanvasPixelArray* pixelBuffer =
+ V8Proxy::ToNativeObject<CanvasPixelArray>(
+ V8ClassIndex::CANVASPIXELARRAY,
+ info.Holder());
+
+ if ((index < 0) || (index >= pixelBuffer->length())) {
+ return v8::Undefined();
+ }
+ unsigned char result;
+ if (!pixelBuffer->get(index, result)) {
+ return v8::Undefined();
+ }
+ return v8::Number::New(result);
+}
+
+
+// Set the specified value in the pixel buffer. Accesses outside the valid pixel
+// buffer range are silently ignored.
+INDEXED_PROPERTY_SETTER(CanvasPixelArray) {
+ INC_STATS("DOM.CanvasPixelArray.IndexedPropertySetter");
+ CanvasPixelArray* pixelBuffer =
+ V8Proxy::ToNativeObject<CanvasPixelArray>(
+ V8ClassIndex::CANVASPIXELARRAY,
+ info.Holder());
+
+ if ((index >= 0) && (index < pixelBuffer->length())) {
+ pixelBuffer->set(index, value->NumberValue());
+ }
+ return value;
+}
+
+
+} // namespace WebCore
diff --git a/V8Binding/v8/V8InitializeThreading.cpp b/V8Binding/v8/V8InitializeThreading.cpp
new file mode 100644
index 0000000..869e374
--- /dev/null
+++ b/V8Binding/v8/V8InitializeThreading.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8InitializeThreading.h"
+#include <wtf/Threading.h>
+
+namespace V8 {
+
+void initializeThreading() {
+ static bool initializedThreading = false;
+ if (!initializedThreading) {
+ WTF::initializeThreading();
+ initializedThreading = true;
+ }
+}
+
+} // namespace JSC
+
diff --git a/V8Binding/v8/V8InitializeThreading.h b/V8Binding/v8/V8InitializeThreading.h
new file mode 100644
index 0000000..e548441
--- /dev/null
+++ b/V8Binding/v8/V8InitializeThreading.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InitializeThreading_h
+#define InitializeThreading_h
+
+namespace V8 {
+
+ // This function must be called from the main thread. It is safe to call it repeatedly.
+ // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly.
+ void initializeThreading();
+}
+
+#endif // InitializeThreading_h
diff --git a/V8Binding/v8/V8MessagePortCustom.cpp b/V8Binding/v8/V8MessagePortCustom.cpp
new file mode 100644
index 0000000..6405b67
--- /dev/null
+++ b/V8Binding/v8/V8MessagePortCustom.cpp
@@ -0,0 +1,239 @@
+/*
+* Copyright (C) 2009 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_proxy.h"
+
+#include "V8Document.h"
+#include "V8HTMLDocument.h"
+#include "V8ObjectEventListener.h"
+
+#include "ExceptionCode.h"
+#include "MessagePort.h"
+
+namespace WebCore {
+
+// FIXME: merge these with XHR's CreateHiddenXHRDependency
+
+// Use an array to hold dependents. It works like a ref-counted scheme.
+// A value can be added more than once to the xhr object.
+static void CreateHiddenDependency(v8::Local<v8::Object> object,
+ v8::Local<v8::Value> value)
+{
+ ASSERT(V8Proxy::GetDOMWrapperType(object) == V8ClassIndex::MESSAGEPORT);
+ v8::Local<v8::Value> cache = object->GetInternalField(V8Custom::kMessagePortRequestCacheIndex);
+ if (cache->IsNull() || cache->IsUndefined()) {
+ cache = v8::Array::New();
+ object->SetInternalField(V8Custom::kMessagePortRequestCacheIndex, cache);
+ }
+
+ v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache);
+ cacheArray->Set(v8::Integer::New(cacheArray->Length()), value);
+}
+
+static void RemoveHiddenDependency(v8::Local<v8::Object> object,
+ v8::Local<v8::Value> value)
+{
+ ASSERT(V8Proxy::GetDOMWrapperType(object) == V8ClassIndex::MESSAGEPORT);
+ v8::Local<v8::Value> cache = object->GetInternalField(V8Custom::kMessagePortRequestCacheIndex);
+ ASSERT(cache->IsArray());
+ v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache);
+ for (int i = cacheArray->Length() - 1; i >= 0; i--) {
+ v8::Local<v8::Value> cached = cacheArray->Get(v8::Integer::New(i));
+ if (cached->StrictEquals(value)) {
+ cacheArray->Delete(i);
+ return;
+ }
+ }
+
+ // We should only get here if we try to remove an event listener that was
+ // never added.
+}
+
+ACCESSOR_GETTER(MessagePortOnmessage)
+{
+ INC_STATS("DOM.MessagePort.onmessage._get");
+ MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(
+ V8ClassIndex::MESSAGEPORT, info.Holder());
+ if (messagePort->onmessage()) {
+ V8ObjectEventListener* listener =
+ static_cast<V8ObjectEventListener*>(messagePort->onmessage());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(MessagePortOnmessage)
+{
+ INC_STATS("DOM.MessagePort.onmessage._set");
+ MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(
+ V8ClassIndex::MESSAGEPORT, info.Holder());
+ if (value->IsNull()) {
+ if (messagePort->onmessage()) {
+ V8ObjectEventListener* listener =
+ static_cast<V8ObjectEventListener*>(messagePort->onmessage());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ RemoveHiddenDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener
+ messagePort->setOnmessage(0);
+
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ messagePort->setOnmessage(listener);
+ CreateHiddenDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(MessagePortOnclose)
+{
+ INC_STATS("DOM.MessagePort.onclose._get");
+ MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(
+ V8ClassIndex::MESSAGEPORT, info.Holder());
+ if (messagePort->onclose()) {
+ V8ObjectEventListener* listener =
+ static_cast<V8ObjectEventListener*>(messagePort->onclose());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(MessagePortOnclose)
+{
+ INC_STATS("DOM.MessagePort.onclose._set");
+ MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(
+ V8ClassIndex::MESSAGEPORT, info.Holder());
+ if (value->IsNull()) {
+ if (messagePort->onclose()) {
+ V8ObjectEventListener* listener =
+ static_cast<V8ObjectEventListener*>(messagePort->onclose());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ RemoveHiddenDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener
+ messagePort->setOnclose(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ messagePort->setOnclose(listener);
+ CreateHiddenDependency(info.Holder(), value);
+ }
+ }
+}
+
+CALLBACK_FUNC_DECL(MessagePortStartConversation)
+{
+ INC_STATS("DOM.MessagePort.StartConversation()");
+ if (args.Length() < 1) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(
+ V8ClassIndex::MESSAGEPORT, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<MessagePort> port =
+ messagePort->startConversation(messagePort->scriptExecutionContext(),
+ ToWebCoreString(args[0]));
+ v8::Handle<v8::Value> wrapper =
+ V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port.get());
+ return wrapper;
+}
+
+CALLBACK_FUNC_DECL(MessagePortAddEventListener)
+{
+ INC_STATS("DOM.MessagePort.AddEventListener()");
+ MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(
+ V8ClassIndex::MESSAGEPORT, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(args[1], false);
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ messagePort->addEventListener(type, listener, useCapture);
+
+ CreateHiddenDependency(args.Holder(), args[1]);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(MessagePortRemoveEventListener)
+{
+ INC_STATS("DOM.MessagePort.RemoveEventListener()");
+ MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(
+ V8ClassIndex::MESSAGEPORT, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined(); // probably leaked
+
+ RefPtr<EventListener> listener =
+ proxy->FindObjectEventListener(args[1], false);
+
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ messagePort->removeEventListener(type, listener.get(), useCapture);
+
+ RemoveHiddenDependency(args.Holder(), args[1]);
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/V8Binding/v8/V8NPObject.cpp b/V8Binding/v8/V8NPObject.cpp
new file mode 100644
index 0000000..60e66a9
--- /dev/null
+++ b/V8Binding/v8/V8NPObject.cpp
@@ -0,0 +1,369 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#include "v8_custom.h"
+#include "v8_helpers.h"
+#include "V8NPObject.h"
+#include "V8NPUtils.h"
+#include "NPV8Object.h"
+#include "npruntime_priv.h"
+#include "v8_proxy.h"
+#include "dom_wrapper_map.h"
+#include "HTMLPlugInElement.h"
+#include "V8HTMLAppletElement.h"
+#include "V8HTMLEmbedElement.h"
+#include "V8HTMLObjectElement.h"
+
+using namespace WebCore;
+
+enum InvokeFunctionType {
+ INVOKE_METHOD = 1,
+ INVOKE_DEFAULT = 2
+};
+
+// TODO(mbelshe): need comments.
+// Params: holder could be HTMLEmbedElement or NPObject
+static v8::Handle<v8::Value> NPObjectInvokeImpl(const v8::Arguments& args, InvokeFunctionType funcId)
+{
+ NPObject* npobject;
+
+ // These three types are subtypes of HTMLPlugInElement.
+ if (V8HTMLAppletElement::HasInstance(args.Holder()) ||
+ V8HTMLEmbedElement::HasInstance(args.Holder()) ||
+ V8HTMLObjectElement::HasInstance(args.Holder())) {
+ // The holder object is a subtype of HTMLPlugInElement.
+ HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(args.Holder());
+ ScriptInstance scriptInstance = imp->getInstance();
+ if (scriptInstance)
+ npobject = V8Proxy::ToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, scriptInstance->instance());
+ else
+ npobject = NULL;
+ } else {
+ // The holder object is not a subtype of HTMLPlugInElement, it
+ // must be an NPObject which has three internal fields.
+ if (args.Holder()->InternalFieldCount() != V8Custom::kNPObjectInternalFieldCount) {
+ V8Proxy::ThrowError(V8Proxy::REFERENCE_ERROR, "NPMethod called on non-NPObject");
+ return v8::Undefined();
+ }
+ npobject = V8Proxy::ToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, args.Holder());
+ }
+
+ // Verify that our wrapper wasn't using a NPObject which
+ // has already been deleted.
+ if (!npobject || !_NPN_IsAlive(npobject)) {
+ V8Proxy::ThrowError(V8Proxy::REFERENCE_ERROR, "NPObject deleted");
+ return v8::Undefined();
+ }
+
+ // wrap up parameters
+ int argc = args.Length();
+ NPVariant* npArgs = new NPVariant[argc];
+
+ for (int i = 0; i < argc; i++)
+ convertV8ObjectToNPVariant(args[i], npobject, &npArgs[i]);
+
+ NPVariant result;
+ VOID_TO_NPVARIANT(result);
+
+ switch (funcId) {
+ case INVOKE_METHOD:
+ if (npobject->_class->invoke) {
+ v8::Handle<v8::String> function_name(v8::String::Cast(*args.Data()));
+ NPIdentifier ident = getStringIdentifier(function_name);
+ npobject->_class->invoke(npobject, ident, npArgs, argc, &result);
+ }
+ break;
+ case INVOKE_DEFAULT:
+ if (npobject->_class->invokeDefault)
+ npobject->_class->invokeDefault(npobject, npArgs, argc, &result);
+ break;
+ default:
+ break;
+ }
+
+ for (int i=0; i < argc; i++)
+ NPN_ReleaseVariantValue(&npArgs[i]);
+ delete[] npArgs;
+
+ // unwrap return values
+ v8::Handle<v8::Value> rv = convertNPVariantToV8Object(&result, npobject);
+ NPN_ReleaseVariantValue(&result);
+
+ return rv;
+}
+
+
+v8::Handle<v8::Value> NPObjectMethodHandler(const v8::Arguments& args)
+{
+ return NPObjectInvokeImpl(args, INVOKE_METHOD);
+}
+
+
+v8::Handle<v8::Value> NPObjectInvokeDefaultHandler(const v8::Arguments& args)
+{
+ return NPObjectInvokeImpl(args, INVOKE_DEFAULT);
+}
+
+
+static void WeakTemplateCallback(v8::Persistent<v8::Value> obj, void* param);
+
+// NPIdentifier is PrivateIdentifier*.
+static WeakReferenceMap<PrivateIdentifier, v8::FunctionTemplate> \
+ static_template_map(&WeakTemplateCallback);
+
+static void WeakTemplateCallback(v8::Persistent<v8::Value> obj, void* param)
+{
+ PrivateIdentifier* iden = static_cast<PrivateIdentifier*>(param);
+ ASSERT(iden != NULL);
+ ASSERT(static_template_map.contains(iden));
+
+ static_template_map.forget(iden);
+}
+
+
+static v8::Handle<v8::Value> NPObjectGetProperty(v8::Local<v8::Object> self,
+ NPIdentifier ident,
+ v8::Local<v8::Value> key)
+{
+ NPObject* npobject = V8Proxy::ToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, self);
+
+ // Verify that our wrapper wasn't using a NPObject which
+ // has already been deleted.
+ if (!npobject || !_NPN_IsAlive(npobject)) {
+ V8Proxy::ThrowError(V8Proxy::REFERENCE_ERROR, "NPObject deleted");
+ return v8::Handle<v8::Value>();
+ }
+
+ if (npobject->_class->hasProperty &&
+ npobject->_class->hasProperty(npobject, ident) &&
+ npobject->_class->getProperty) {
+
+ NPVariant result;
+ VOID_TO_NPVARIANT(result);
+ if (!npobject->_class->getProperty(npobject, ident, &result))
+ return v8::Handle<v8::Value>();
+
+ v8::Handle<v8::Value> rv = convertNPVariantToV8Object(&result, npobject);
+ NPN_ReleaseVariantValue(&result);
+ return rv;
+ } else if (key->IsString() && npobject->_class->hasMethod && npobject->_class->hasMethod(npobject, ident)) {
+ PrivateIdentifier* id = static_cast<PrivateIdentifier*>(ident);
+ v8::Persistent<v8::FunctionTemplate> desc = static_template_map.get(id);
+ // Cache templates using identifier as the key.
+ if (desc.IsEmpty()) {
+ // Create a new template
+ v8::Local<v8::FunctionTemplate> temp = v8::FunctionTemplate::New();
+ temp->SetCallHandler(NPObjectMethodHandler, key);
+ desc = v8::Persistent<v8::FunctionTemplate>::New(temp);
+ static_template_map.set(id, desc);
+ }
+
+ // FunctionTemplate caches function for each context.
+ v8::Local<v8::Function> func = desc->GetFunction();
+ func->SetName(v8::Handle<v8::String>::Cast(key));
+ return func;
+ }
+
+ return v8::Handle<v8::Value>();
+}
+
+v8::Handle<v8::Value> NPObjectNamedPropertyGetter(v8::Local<v8::String> name,
+ const v8::AccessorInfo& info)
+{
+ NPIdentifier ident = getStringIdentifier(name);
+ return NPObjectGetProperty(info.Holder(), ident, name);
+}
+
+v8::Handle<v8::Value> NPObjectIndexedPropertyGetter(uint32_t index,
+ const v8::AccessorInfo& info)
+{
+ NPIdentifier ident = NPN_GetIntIdentifier(index);
+ return NPObjectGetProperty(info.Holder(), ident, v8::Number::New(index));
+}
+
+v8::Handle<v8::Value> NPObjectGetNamedProperty(v8::Local<v8::Object> self,
+ v8::Local<v8::String> name)
+{
+ NPIdentifier ident = getStringIdentifier(name);
+ return NPObjectGetProperty(self, ident, name);
+}
+
+v8::Handle<v8::Value> NPObjectGetIndexedProperty(v8::Local<v8::Object> self,
+ uint32_t index)
+{
+ NPIdentifier ident = NPN_GetIntIdentifier(index);
+ return NPObjectGetProperty(self, ident, v8::Number::New(index));
+}
+
+static v8::Handle<v8::Value> NPObjectSetProperty(v8::Local<v8::Object> self,
+ NPIdentifier ident,
+ v8::Local<v8::Value> value)
+{
+ NPObject* npobject = V8Proxy::ToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, self);
+
+ // Verify that our wrapper wasn't using a NPObject which
+ // has already been deleted.
+ if (!npobject || !_NPN_IsAlive(npobject)) {
+ V8Proxy::ThrowError(V8Proxy::REFERENCE_ERROR, "NPObject deleted");
+ return value; // intercepted, but an exception was thrown
+ }
+
+ if (npobject->_class->hasProperty &&
+ npobject->_class->hasProperty(npobject, ident) &&
+ npobject->_class->setProperty) {
+
+ NPVariant npvalue;
+ VOID_TO_NPVARIANT(npvalue);
+ convertV8ObjectToNPVariant(value, npobject, &npvalue);
+ bool succ = npobject->_class->setProperty(npobject, ident, &npvalue);
+ NPN_ReleaseVariantValue(&npvalue);
+ if (succ)
+ return value; // intercept the call
+ }
+ return v8::Local<v8::Value>(); // do not intercept the call
+}
+
+
+v8::Handle<v8::Value> NPObjectNamedPropertySetter(v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info)
+{
+ NPIdentifier ident = getStringIdentifier(name);
+ return NPObjectSetProperty(info.Holder(), ident, value);
+}
+
+
+v8::Handle<v8::Value> NPObjectIndexedPropertySetter(uint32_t index,
+ v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info)
+{
+ NPIdentifier ident = NPN_GetIntIdentifier(index);
+ return NPObjectSetProperty(info.Holder(), ident, value);
+}
+
+v8::Handle<v8::Value> NPObjectSetNamedProperty(v8::Local<v8::Object> self,
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value)
+{
+ NPIdentifier ident = getStringIdentifier(name);
+ return NPObjectSetProperty(self, ident, value);
+}
+
+v8::Handle<v8::Value> NPObjectSetIndexedProperty(v8::Local<v8::Object> self,
+ uint32_t index,
+ v8::Local<v8::Value> value)
+{
+ NPIdentifier ident = NPN_GetIntIdentifier(index);
+ return NPObjectSetProperty(self, ident, value);
+}
+
+
+static void WeakNPObjectCallback(v8::Persistent<v8::Value> obj, void* param);
+
+static DOMWrapperMap<NPObject> staticNpobjectMap(&WeakNPObjectCallback);
+
+static void WeakNPObjectCallback(v8::Persistent<v8::Value> obj, void* param)
+{
+ NPObject* npobject = static_cast<NPObject*>(param);
+ ASSERT(staticNpobjectMap.contains(npobject));
+ ASSERT(npobject != NULL);
+
+ // Must remove from our map before calling NPN_ReleaseObject().
+ // NPN_ReleaseObject can call ForgetV8ObjectForNPObject, which
+ // uses the table as well.
+ staticNpobjectMap.forget(npobject);
+
+ if (_NPN_IsAlive(npobject))
+ NPN_ReleaseObject(npobject);
+}
+
+
+v8::Local<v8::Object> CreateV8ObjectForNPObject(NPObject* object, NPObject* root)
+{
+ static v8::Persistent<v8::FunctionTemplate> npObjectDesc;
+
+ ASSERT(v8::Context::InContext());
+
+ // If this is a v8 object, just return it.
+ if (object->_class == npScriptObjectClass) {
+ V8NPObject* v8npobject = reinterpret_cast<V8NPObject*>(object);
+ return v8::Local<v8::Object>::New(v8npobject->v8Object);
+ }
+
+ // If we've already wrapped this object, just return it.
+ if (staticNpobjectMap.contains(object))
+ return v8::Local<v8::Object>::New(staticNpobjectMap.get(object));
+
+ // TODO: we should create a Wrapper type as a subclass of JSObject.
+ // It has two internal fields, field 0 is the wrapped pointer,
+ // and field 1 is the type. There should be an api function that
+ // returns unused type id.
+ // The same Wrapper type can be used by DOM bindings.
+ if (npObjectDesc.IsEmpty()) {
+ npObjectDesc = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
+ npObjectDesc->InstanceTemplate()->SetInternalFieldCount(V8Custom::kNPObjectInternalFieldCount);
+ npObjectDesc->InstanceTemplate()->SetNamedPropertyHandler(NPObjectNamedPropertyGetter, NPObjectNamedPropertySetter);
+ npObjectDesc->InstanceTemplate()->SetIndexedPropertyHandler(NPObjectIndexedPropertyGetter, NPObjectIndexedPropertySetter);
+ npObjectDesc->InstanceTemplate()->SetCallAsFunctionHandler(NPObjectInvokeDefaultHandler);
+ }
+
+ v8::Handle<v8::Function> func = npObjectDesc->GetFunction();
+ v8::Local<v8::Object> value = SafeAllocation::NewInstance(func);
+
+ // If we were unable to allocate the instance we avoid wrapping
+ // and registering the NP object.
+ if (value.IsEmpty())
+ return value;
+
+ WrapNPObject(value, object);
+
+ // KJS retains the object as part of its wrapper (see Bindings::CInstance)
+ NPN_RetainObject(object);
+
+ _NPN_RegisterObject(object, root);
+
+ // Maintain a weak pointer for v8 so we can cleanup the object.
+ v8::Persistent<v8::Object> weakRef = v8::Persistent<v8::Object>::New(value);
+ staticNpobjectMap.set(object, weakRef);
+
+ return value;
+}
+
+void ForgetV8ObjectForNPObject(NPObject* object)
+{
+ if (staticNpobjectMap.contains(object)) {
+ v8::HandleScope scope;
+ v8::Persistent<v8::Object> handle(staticNpobjectMap.get(object));
+ WebCore::V8Proxy::SetDOMWrapper(handle, WebCore::V8ClassIndex::NPOBJECT, NULL);
+ staticNpobjectMap.forget(object);
+ NPN_ReleaseObject(object);
+ }
+}
diff --git a/V8Binding/v8/V8NPObject.h b/V8Binding/v8/V8NPObject.h
new file mode 100644
index 0000000..04cbff1
--- /dev/null
+++ b/V8Binding/v8/V8NPObject.h
@@ -0,0 +1,57 @@
+// 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_npobject_h
+#define v8_npobject_h
+
+#include <v8.h>
+#if PLATFORM(CHROMIUM)
+#include "third_party/npapi/bindings/npruntime.h"
+#else
+#include "bridge/npruntime.h" // use WebCore version
+#endif
+
+// These functions can be replaced by normal JS operation.
+// Getters
+v8::Handle<v8::Value> NPObjectNamedPropertyGetter(v8::Local<v8::String> name,
+ const v8::AccessorInfo& info);
+v8::Handle<v8::Value> NPObjectIndexedPropertyGetter(uint32_t index,
+ const v8::AccessorInfo& info);
+v8::Handle<v8::Value> NPObjectGetNamedProperty(v8::Local<v8::Object> self,
+ v8::Local<v8::String> name);
+v8::Handle<v8::Value> NPObjectGetIndexedProperty(v8::Local<v8::Object> self,
+ uint32_t index);
+
+// Setters
+v8::Handle<v8::Value> NPObjectNamedPropertySetter(v8::Local<v8::String> name,
+ v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info);
+v8::Handle<v8::Value> NPObjectIndexedPropertySetter(uint32_t index,
+ const v8::AccessorInfo& info);
+v8::Handle<v8::Value> NPObjectSetNamedProperty(v8::Local<v8::Object> self,
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> value);
+v8::Handle<v8::Value> NPObjectSetIndexedProperty(v8::Local<v8::Object> self,
+ uint32_t index,
+ v8::Local<v8::Value> value);
+
+v8::Handle<v8::Value> NPObjectInvokeDefaultHandler(const v8::Arguments& args);
+
+// Get a wrapper for a NPObject.
+// If the object is already wrapped, the pre-existing wrapper
+// will be returned.
+// If the object is not wrapped, wrap it, and give V8 a weak
+// reference to the wrapper which will cleanup when there are
+// no more JS references to the object.
+v8::Local<v8::Object> CreateV8ObjectForNPObject(NPObject* object, NPObject *root);
+
+// Tell V8 to forcibly remove an object.
+// This is used at plugin teardown so that the caller can
+// aggressively unload the plugin library. After calling this
+// function, the persistent handle to the wrapper will be
+// gone, and the wrapped NPObject will be removed so that
+// it cannot be referred to.
+void ForgetV8ObjectForNPObject(NPObject*object);
+
+#endif // v8_npobject_h
diff --git a/V8Binding/v8/V8NPUtils.cpp b/V8Binding/v8/V8NPUtils.cpp
new file mode 100644
index 0000000..04e6ede
--- /dev/null
+++ b/V8Binding/v8/V8NPUtils.cpp
@@ -0,0 +1,124 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#include "V8NPUtils.h"
+
+#include "DOMWindow.h"
+#include "Frame.h"
+#include "PlatformString.h"
+#undef LOG
+
+#include "npruntime_priv.h"
+#include "NPV8Object.h"
+#include "V8NPObject.h"
+#include "v8_proxy.h"
+
+void convertV8ObjectToNPVariant(v8::Local<v8::Value> object, NPObject *owner, NPVariant* result)
+{
+ VOID_TO_NPVARIANT(*result);
+
+ // It is really the caller's responsibility to deal with the empty handle
+ // case because there could be different actions to take in different
+ // contexts.
+ ASSERT(!object.IsEmpty());
+
+ if (object.IsEmpty())
+ return;
+
+ if (object->IsInt32())
+ INT32_TO_NPVARIANT(object->NumberValue(), *result);
+ else if (object->IsNumber())
+ DOUBLE_TO_NPVARIANT(object->NumberValue(), *result);
+ else if (object->IsBoolean())
+ BOOLEAN_TO_NPVARIANT(object->BooleanValue(), *result);
+ else if (object->IsNull())
+ NULL_TO_NPVARIANT(*result);
+ else if (object->IsUndefined())
+ VOID_TO_NPVARIANT(*result);
+ else if (object->IsString()) {
+ v8::String::Utf8Value utf8(object);
+ char* utf8_chars = strdup(*utf8);
+ STRINGN_TO_NPVARIANT(utf8_chars, utf8.length(), *result);
+ } else if (object->IsObject()) {
+ WebCore::DOMWindow* window = WebCore::V8Proxy::retrieveWindow();
+ NPObject* npobject = npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(object), window);
+ if (npobject)
+ _NPN_RegisterObject(npobject, owner);
+ OBJECT_TO_NPVARIANT(npobject, *result);
+ }
+}
+
+
+v8::Handle<v8::Value> convertNPVariantToV8Object(const NPVariant* variant, NPObject* npobject)
+{
+ NPVariantType type = variant->type;
+
+ if (type == NPVariantType_Int32)
+ return v8::Integer::New(NPVARIANT_TO_INT32(*variant));
+ if (type == NPVariantType_Double)
+ return v8::Number::New(NPVARIANT_TO_DOUBLE(*variant));
+ if (type == NPVariantType_Bool)
+ return NPVARIANT_TO_BOOLEAN(*variant) ? v8::True() : v8::False();
+ if (type == NPVariantType_Null)
+ return v8::Null();
+ if (type == NPVariantType_Void)
+ return v8::Undefined();
+ if (type == NPVariantType_String) {
+ NPString src = NPVARIANT_TO_STRING(*variant);
+ return v8::String::New(src.UTF8Characters, src.UTF8Length);
+ }
+ if (type == NPVariantType_Object) {
+ NPObject* obj = NPVARIANT_TO_OBJECT(*variant);
+ if (obj->_class == npScriptObjectClass)
+ return reinterpret_cast<V8NPObject*>(obj)->v8Object;
+ return CreateV8ObjectForNPObject(obj, npobject);
+ }
+ return v8::Undefined();
+}
+
+// Helper function to create an NPN String Identifier from a v8 string.
+NPIdentifier getStringIdentifier(v8::Handle<v8::String> str)
+{
+ const int kStackBufSize = 100;
+
+ int bufLen = str->Length() + 1;
+ if (bufLen <= kStackBufSize) {
+ // Use local stack buffer to avoid heap allocations for small strings.
+ // Here we should only use the stack space for stack_buf when it's used,
+ // not when we use the heap.
+ char stackBuf[kStackBufSize];
+ str->WriteAscii(stackBuf);
+ return NPN_GetStringIdentifier(stackBuf);
+ }
+
+ v8::String::AsciiValue ascii(str);
+ return NPN_GetStringIdentifier(*ascii);
+}
diff --git a/V8Binding/v8/V8NPUtils.h b/V8Binding/v8/V8NPUtils.h
new file mode 100644
index 0000000..2e07e66
--- /dev/null
+++ b/V8Binding/v8/V8NPUtils.h
@@ -0,0 +1,31 @@
+// 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_np_utils_h
+#define v8_np_utils_h
+
+#include <v8.h>
+#if PLATFORM(CHROMIUM)
+#include "third_party/npapi/bindings/npruntime.h"
+#else
+#include "bridge/npruntime.h" // use WebCore version
+#endif
+
+namespace WebCore {
+ class Frame;
+}
+
+// Convert a V8 Value of any type (string, bool, object, etc) to a NPVariant.
+void convertV8ObjectToNPVariant(v8::Local<v8::Value> object, NPObject *owner, NPVariant* result);
+
+// Convert a NPVariant (string, bool, object, etc) back to a V8 Value.
+// The owner object is the NPObject which relates to the object, if the object
+// is an Object. The created NPObject will be tied to the lifetime of the
+// owner.
+v8::Handle<v8::Value> convertNPVariantToV8Object(const NPVariant* value, NPObject* owner);
+
+// Helper function to create an NPN String Identifier from a v8 string.
+NPIdentifier getStringIdentifier(v8::Handle<v8::String> str);
+
+#endif // v8_np_utils_h
diff --git a/V8Binding/v8/V8SVGPODTypeWrapper.h b/V8Binding/v8/V8SVGPODTypeWrapper.h
new file mode 100644
index 0000000..79553c2
--- /dev/null
+++ b/V8Binding/v8/V8SVGPODTypeWrapper.h
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 The Chromium Authors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8SVGPODTypeWrapper_h
+#define V8SVGPODTypeWrapper_h
+
+#if ENABLE(SVG)
+
+#include "config.h"
+#include "SVGElement.h"
+#include "SVGList.h"
+#include <wtf/Assertions.h>
+#include <wtf/RefCounted.h>
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+template<typename PODType>
+class V8SVGPODTypeWrapper : public RefCounted<V8SVGPODTypeWrapper<PODType> > {
+public:
+ V8SVGPODTypeWrapper() { }
+ virtual ~V8SVGPODTypeWrapper() { }
+ virtual operator PODType() = 0;
+ virtual void commitChange(PODType, SVGElement*) = 0;
+};
+
+template<typename PODType>
+class V8SVGPODTypeWrapperCreatorForList : public V8SVGPODTypeWrapper<PODType>
+{
+public:
+ typedef PODType (SVGPODListItem<PODType>::*GetterMethod)() const;
+ typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType);
+
+ V8SVGPODTypeWrapperCreatorForList(SVGPODListItem<PODType>* creator, const QualifiedName& attributeName)
+ : m_creator(creator)
+ , m_getter(&SVGPODListItem<PODType>::value)
+ , m_setter(&SVGPODListItem<PODType>::setValue)
+ , m_associatedAttributeName(attributeName)
+ {
+ ASSERT(m_creator);
+ ASSERT(m_getter);
+ ASSERT(m_setter);
+ }
+
+ virtual ~V8SVGPODTypeWrapperCreatorForList() { }
+
+ // Getter wrapper
+ virtual operator PODType() { return (m_creator.get()->*m_getter)(); }
+
+ // Setter wrapper
+ virtual void commitChange(PODType type, SVGElement* context)
+ {
+ if (!m_setter)
+ return;
+
+ (m_creator.get()->*m_setter)(type);
+
+ if (context)
+ context->svgAttributeChanged(m_associatedAttributeName);
+ }
+
+private:
+ // Update callbacks
+ RefPtr<SVGPODListItem<PODType> > m_creator;
+ GetterMethod m_getter;
+ SetterMethod m_setter;
+ const QualifiedName& m_associatedAttributeName;
+};
+
+template<typename PODType>
+class V8SVGStaticPODTypeWrapper : public V8SVGPODTypeWrapper<PODType>
+{
+public:
+ V8SVGStaticPODTypeWrapper(PODType type)
+ : m_podType(type)
+ { }
+
+ virtual ~V8SVGStaticPODTypeWrapper() { }
+
+ // Getter wrapper
+ virtual operator PODType() { return m_podType; }
+
+ // Setter wrapper
+ virtual void commitChange(PODType type, SVGElement*)
+ {
+ m_podType = type;
+ }
+
+private:
+ PODType m_podType;
+};
+
+template<typename PODType, typename ParentTypeArg>
+class V8SVGStaticPODTypeWrapperWithPODTypeParent : public V8SVGStaticPODTypeWrapper<PODType> {
+public:
+ typedef V8SVGPODTypeWrapper<ParentTypeArg> ParentType;
+
+ V8SVGStaticPODTypeWrapperWithPODTypeParent(PODType type, ParentType* parent)
+ : V8SVGStaticPODTypeWrapper<PODType>(type)
+ , m_parentType(parent)
+ {
+ }
+
+ virtual void commitChange(PODType type, SVGElement* context)
+ {
+ V8SVGStaticPODTypeWrapper<PODType>::commitChange(type, context);
+ m_parentType->commitChange(ParentTypeArg(type), context);
+ }
+
+private:
+ RefPtr<ParentType> m_parentType;
+};
+
+template<typename PODType, typename ParentType>
+class V8SVGStaticPODTypeWrapperWithParent : public V8SVGPODTypeWrapper<PODType> {
+public:
+ typedef PODType (ParentType::*GetterMethod)() const;
+ typedef void (ParentType::*SetterMethod)(const PODType&);
+
+ V8SVGStaticPODTypeWrapperWithParent(ParentType* parent, GetterMethod getter, SetterMethod setter)
+ : m_parent(parent)
+ , m_getter(getter)
+ , m_setter(setter)
+ {
+ ASSERT(m_parent);
+ ASSERT(m_getter);
+ ASSERT(m_setter);
+ }
+
+ virtual operator PODType()
+ {
+ return (m_parent.get()->*m_getter)();
+ }
+
+ virtual void commitChange(PODType type, SVGElement* context)
+ {
+ (m_parent.get()->*m_setter)(type);
+ }
+
+private:
+ // Update callbacks
+ RefPtr<ParentType> m_parent;
+ GetterMethod m_getter;
+ SetterMethod m_setter;
+};
+
+template<typename PODType, typename PODTypeCreator>
+class V8SVGDynamicPODTypeWrapper : public V8SVGPODTypeWrapper<PODType>
+{
+public:
+ typedef PODType (PODTypeCreator::*GetterMethod)() const;
+ typedef void (PODTypeCreator::*SetterMethod)(PODType);
+ typedef void (*CacheRemovalCallback)(V8SVGPODTypeWrapper<PODType>*);
+
+ V8SVGDynamicPODTypeWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter, CacheRemovalCallback cacheRemovalCallback)
+ : m_creator(creator)
+ , m_getter(getter)
+ , m_setter(setter)
+ , m_cacheRemovalCallback(cacheRemovalCallback)
+ {
+ ASSERT(creator);
+ ASSERT(getter);
+ ASSERT(setter);
+ ASSERT(cacheRemovalCallback);
+ }
+
+ virtual ~V8SVGDynamicPODTypeWrapper() {
+ ASSERT(m_cacheRemovalCallback);
+
+ (*m_cacheRemovalCallback)(this);
+ }
+
+ // Getter wrapper
+ virtual operator PODType() { return (m_creator.get()->*m_getter)(); }
+
+ // Setter wrapper
+ virtual void commitChange(PODType type, SVGElement* context)
+ {
+ (m_creator.get()->*m_setter)(type);
+
+ if (context)
+ context->svgAttributeChanged(m_creator->associatedAttributeName());
+ }
+
+private:
+ // Update callbacks
+ RefPtr<PODTypeCreator> m_creator;
+ GetterMethod m_getter;
+ SetterMethod m_setter;
+ CacheRemovalCallback m_cacheRemovalCallback;
+};
+
+// Caching facilities
+template<typename PODType, typename PODTypeCreator>
+struct PODTypeWrapperCacheInfo {
+ typedef PODType (PODTypeCreator::*GetterMethod)() const;
+ typedef void (PODTypeCreator::*SetterMethod)(PODType);
+
+ // Empty value
+ PODTypeWrapperCacheInfo()
+ : creator(0)
+ , getter(0)
+ , setter(0)
+ { }
+
+ // Deleted value
+ explicit PODTypeWrapperCacheInfo(WTF::HashTableDeletedValueType)
+ : creator(reinterpret_cast<PODTypeCreator*>(-1))
+ , getter(0)
+ , setter(0)
+ {
+ }
+ bool isHashTableDeletedValue() const
+ {
+ return creator == reinterpret_cast<PODTypeCreator*>(-1);
+ }
+
+ PODTypeWrapperCacheInfo(PODTypeCreator* _creator, GetterMethod _getter, SetterMethod _setter)
+ : creator(_creator)
+ , getter(_getter)
+ , setter(_setter)
+ {
+ ASSERT(creator);
+ ASSERT(getter);
+ }
+
+ bool operator==(const PODTypeWrapperCacheInfo& other) const
+ {
+ return creator == other.creator && getter == other.getter && setter == other.setter;
+ }
+
+ PODTypeCreator* creator;
+ GetterMethod getter;
+ SetterMethod setter;
+};
+
+template<typename PODType, typename PODTypeCreator>
+struct PODTypeWrapperCacheInfoHash {
+ static unsigned hash(const PODTypeWrapperCacheInfo<PODType, PODTypeCreator>& info)
+ {
+ unsigned creator = reinterpret_cast<unsigned>(info.creator);
+ unsigned getter = reinterpret_cast<unsigned>(*(void**)&info.getter);
+ unsigned setter = reinterpret_cast<unsigned>(*(void**)&info.setter);
+ return (creator * 13) + getter ^ (setter >> 2);
+ }
+
+ static bool equal(const PODTypeWrapperCacheInfo<PODType, PODTypeCreator>& a, const PODTypeWrapperCacheInfo<PODType, PODTypeCreator>& b)
+ {
+ return a == b;
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+template<typename PODType, typename PODTypeCreator>
+struct PODTypeWrapperCacheInfoTraits : WTF::GenericHashTraits<PODTypeWrapperCacheInfo<PODType, PODTypeCreator> > {
+ typedef PODTypeWrapperCacheInfo<PODType, PODTypeCreator> CacheInfo;
+
+ static const bool emptyValueIsZero = true;
+ static const bool needsDestruction = false;
+
+ static const CacheInfo& emptyValue()
+ {
+ static CacheInfo key;
+ return key;
+ }
+
+ static void constructDeletedValue(CacheInfo& slot)
+ {
+ new (&slot) CacheInfo(WTF::HashTableDeletedValue);
+ }
+
+ static bool isDeletedValue(const CacheInfo& value)
+ {
+ return value.isHashTableDeletedValue();
+ }
+};
+
+template<typename PODType, typename PODTypeCreator>
+class V8SVGDynamicPODTypeWrapperCache
+{
+public:
+ typedef PODType (PODTypeCreator::*GetterMethod)() const;
+ typedef void (PODTypeCreator::*SetterMethod)(PODType);
+
+ typedef PODTypeWrapperCacheInfo<PODType, PODTypeCreator> CacheInfo;
+ typedef PODTypeWrapperCacheInfoHash<PODType, PODTypeCreator> CacheInfoHash;
+ typedef PODTypeWrapperCacheInfoTraits<PODType, PODTypeCreator> CacheInfoTraits;
+
+ typedef V8SVGPODTypeWrapper<PODType> WrapperBase;
+ typedef V8SVGDynamicPODTypeWrapper<PODType, PODTypeCreator> DynamicWrapper;
+
+ typedef HashMap<CacheInfo, DynamicWrapper*, CacheInfoHash, CacheInfoTraits> DynamicWrapperHashMap;
+ typedef typename DynamicWrapperHashMap::const_iterator DynamicWrapperHashMapIterator;
+
+ static DynamicWrapperHashMap& dynamicWrapperHashMap()
+ {
+ static DynamicWrapperHashMap _dynamicWrapperHashMap;
+ return _dynamicWrapperHashMap;
+ }
+
+ // Used for readwrite attributes only
+ static WrapperBase* lookupOrCreateWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter)
+ {
+ DynamicWrapperHashMap& map(dynamicWrapperHashMap());
+ CacheInfo info(creator, getter, setter);
+
+ if (map.contains(info))
+ return map.get(info);
+
+ DynamicWrapper* wrapper = new V8SVGDynamicPODTypeWrapper<PODType, PODTypeCreator>(
+ creator, getter, setter, forgetWrapper);
+ map.set(info, wrapper);
+ return wrapper;
+ }
+
+ static void forgetWrapper(V8SVGPODTypeWrapper<PODType>* wrapper)
+ {
+ DynamicWrapperHashMap& map(dynamicWrapperHashMap());
+
+ DynamicWrapperHashMapIterator it = map.begin();
+ DynamicWrapperHashMapIterator end = map.end();
+
+ for (; it != end; ++it) {
+ if (it->second != wrapper)
+ continue;
+
+ // It's guaranteed that there's just one object we need to take care of.
+ map.remove(it->first);
+ break;
+ }
+ }
+};
+
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // V8SVGPODTypeWrapper_h
diff --git a/V8Binding/v8/V8WorkerContextCustom.cpp b/V8Binding/v8/V8WorkerContextCustom.cpp
new file mode 100644
index 0000000..e646bb5
--- /dev/null
+++ b/V8Binding/v8/V8WorkerContextCustom.cpp
@@ -0,0 +1,230 @@
+// Copyright (c) 2009, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_proxy.h"
+#include "WorkerContextExecutionProxy.h"
+
+#include "ExceptionCode.h"
+#include "MessagePort.h"
+#include "NotImplemented.h"
+#include "V8Document.h"
+#include "V8HTMLDocument.h"
+#include "V8WorkerContextEventListener.h"
+#include "WorkerContext.h"
+
+namespace WebCore {
+
+// TODO(mbelshe) - merge these with XHR's CreateHiddenXHRDependency
+
+// Use an array to hold dependents. It works like a ref-counted scheme.
+// A value can be added more than once to the xhr object.
+static void CreateHiddenDependency(v8::Local<v8::Object> object,
+ v8::Local<v8::Value> value) {
+ ASSERT(V8Proxy::GetDOMWrapperType(object) == V8ClassIndex::WORKERCONTEXT);
+ v8::Local<v8::Value> cache =
+ object->GetInternalField(V8Custom::kWorkerContextRequestCacheIndex);
+ if (cache->IsNull() || cache->IsUndefined()) {
+ cache = v8::Array::New();
+ object->SetInternalField(V8Custom::kWorkerContextRequestCacheIndex, cache);
+ }
+
+ v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
+ cache_array->Set(v8::Integer::New(cache_array->Length()), value);
+}
+
+static void RemoveHiddenDependency(v8::Local<v8::Object> object,
+ v8::Local<v8::Value> value) {
+ ASSERT(V8Proxy::GetDOMWrapperType(object) == V8ClassIndex::WORKERCONTEXT);
+ v8::Local<v8::Value> cache =
+ object->GetInternalField(V8Custom::kWorkerContextRequestCacheIndex);
+ ASSERT(cache->IsArray());
+ v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
+ for (int i = cache_array->Length() - 1; i >= 0; i--) {
+ v8::Local<v8::Value> cached = cache_array->Get(v8::Integer::New(i));
+ if (cached->StrictEquals(value)) {
+ cache_array->Delete(i);
+ return;
+ }
+ }
+
+ // We should only get here if we try to remove an event listener that was
+ // never added.
+}
+
+ACCESSOR_GETTER(WorkerContextSelf) {
+ INC_STATS(L"DOM.WorkerContext.self._get");
+ WorkerContext* imp = V8Proxy::ToNativeObject<WorkerContext>(
+ V8ClassIndex::WORKERCONTEXT, info.Holder());
+ return WorkerContextExecutionProxy::WorkerContextToV8Object(imp);
+}
+
+ACCESSOR_GETTER(WorkerContextOnmessage) {
+ INC_STATS(L"DOM.WorkerContext.onmessage._get");
+ WorkerContext* imp = V8Proxy::ToNativeObject<WorkerContext>(
+ V8ClassIndex::WORKERCONTEXT, info.Holder());
+ if (imp->onmessage()) {
+ V8WorkerContextEventListener* listener =
+ static_cast<V8WorkerContextEventListener*>(imp->onmessage());
+ v8::Local<v8::Object> v8_listener = listener->getListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(WorkerContextOnmessage) {
+ INC_STATS(L"DOM.WorkerContext.onmessage._set");
+ WorkerContext* imp = V8Proxy::ToNativeObject<WorkerContext>(
+ V8ClassIndex::WORKERCONTEXT, info.Holder());
+ V8WorkerContextEventListener* old_listener =
+ static_cast<V8WorkerContextEventListener*>(imp->onmessage());
+ if (value->IsNull()) {
+ if (imp->onmessage()) {
+ v8::Local<v8::Object> old_v8_listener = old_listener->getListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnmessage(0);
+
+ } else {
+ RefPtr<V8EventListener> listener =
+ imp->script()->proxy()->FindOrCreateEventListener(
+ v8::Local<v8::Object>::Cast(value), false, false);
+ if (listener) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener =
+ old_listener->getListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ imp->setOnmessage(listener);
+ CreateHiddenDependency(info.Holder(), value);
+ }
+ }
+}
+
+v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args,
+ bool singleShot) {
+ WorkerContext* imp = V8Proxy::ToNativeObject<WorkerContext>(
+ V8ClassIndex::WORKERCONTEXT, args.Holder());
+
+ int delay = ToInt32(args[1]);
+
+ notImplemented();
+
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> ClearTimeoutOrInterval(const v8::Arguments& args) {
+ WorkerContext* imp = V8Proxy::ToNativeObject<WorkerContext>(
+ V8ClassIndex::WORKERCONTEXT, args.Holder());
+
+ bool ok = false;
+ int tid = ToInt32(args[0], ok);
+ if (ok) {
+ imp->removeTimeout(tid);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WorkerContextImportScripts) {
+ INC_STATS(L"DOM.WorkerContext.importScripts()");
+ notImplemented();
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WorkerContextSetTimeout) {
+ INC_STATS(L"DOM.WorkerContext.setTimeout()");
+ return SetTimeoutOrInterval(args, true);
+}
+
+CALLBACK_FUNC_DECL(WorkerContextClearTimeout) {
+ INC_STATS(L"DOM.WorkerContext.clearTimeout()");
+ return ClearTimeoutOrInterval(args);
+}
+
+CALLBACK_FUNC_DECL(WorkerContextSetInterval) {
+ INC_STATS(L"DOM.WorkerContext.setInterval()");
+ return SetTimeoutOrInterval(args, false);
+}
+
+CALLBACK_FUNC_DECL(WorkerContextClearInterval) {
+ INC_STATS(L"DOM.WorkerContext.clearInterval()");
+ return ClearTimeoutOrInterval(args);
+}
+
+CALLBACK_FUNC_DECL(WorkerContextAddEventListener) {
+ INC_STATS(L"DOM.WorkerContext.addEventListener()");
+ WorkerContext* imp = V8Proxy::ToNativeObject<WorkerContext>(
+ V8ClassIndex::WORKERCONTEXT, args.Holder());
+
+ RefPtr<V8EventListener> listener =
+ imp->script()->proxy()->FindOrCreateEventListener(
+ v8::Local<v8::Object>::Cast(args[1]), false, false);
+
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->addEventListener(type, listener, useCapture);
+
+ CreateHiddenDependency(args.Holder(), args[1]);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WorkerContextRemoveEventListener) {
+ INC_STATS(L"DOM.WorkerContext.removeEventListener()");
+ WorkerContext* imp = V8Proxy::ToNativeObject<WorkerContext>(
+ V8ClassIndex::WORKERCONTEXT, args.Holder());
+ WorkerContextExecutionProxy* proxy = imp->script()->proxy();
+
+ RefPtr<V8EventListener> listener = proxy->FindOrCreateEventListener(
+ v8::Local<v8::Object>::Cast(args[1]), false, true);
+
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->removeEventListener(type, listener.get(), useCapture);
+
+ RemoveHiddenDependency(args.Holder(), args[1]);
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/V8Binding/v8/V8WorkerCustom.cpp b/V8Binding/v8/V8WorkerCustom.cpp
new file mode 100644
index 0000000..1f7e5fe
--- /dev/null
+++ b/V8Binding/v8/V8WorkerCustom.cpp
@@ -0,0 +1,282 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_proxy.h"
+
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "MessagePort.h"
+#include "V8Document.h"
+#include "V8HTMLDocument.h"
+#include "V8ObjectEventListener.h"
+#include "Worker.h"
+#include "WorkerContextExecutionProxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WorkerConstructor) {
+ INC_STATS(L"DOM.Worker.Constructor");
+
+ if (!WorkerContextExecutionProxy::isWebWorkersEnabled()) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Worker is not enabled.");
+ return v8::Undefined();
+ }
+
+ if (!args.IsConstructCall()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR,
+ "DOM object constructor cannot be called as a function.");
+ return v8::Undefined();
+ }
+
+ if (args.Length() == 0) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ v8::TryCatch try_catch;
+ v8::Handle<v8::String> script_url = args[0]->ToString();
+ if (try_catch.HasCaught()) {
+ v8::ThrowException(try_catch.Exception());
+ return v8::Undefined();
+ }
+ if (script_url.IsEmpty()) {
+ return v8::Undefined();
+ }
+
+ // Get the document.
+ Frame* frame = V8Proxy::retrieveFrame();
+ if (!frame)
+ return v8::Undefined();
+ Document* document = frame->document();
+
+ // Create the worker object.
+ // Note: it's OK to let this RefPtr go out of scope because we also call
+ // SetDOMWrapper(), which effectively holds a reference to obj.
+ ExceptionCode ec = 0;
+ RefPtr<Worker> obj = Worker::create(
+ ToWebCoreString(script_url), document, ec);
+
+ // Setup the standard wrapper object internal fields.
+ v8::Handle<v8::Object> wrapper_object = args.Holder();
+ V8Proxy::SetDOMWrapper(
+ wrapper_object, V8ClassIndex::WORKER, obj.get());
+
+ obj->ref();
+ V8Proxy::SetJSWrapperForActiveDOMObject(
+ obj.get(), v8::Persistent<v8::Object>::New(wrapper_object));
+
+ return wrapper_object;
+}
+
+// TODO(mbelshe) - merge these with XHR's CreateHiddenXHRDependency
+
+// Use an array to hold dependents. It works like a ref-counted scheme.
+// A value can be added more than once to the xhr object.
+static void CreateHiddenDependency(v8::Local<v8::Object> object,
+ v8::Local<v8::Value> value) {
+ ASSERT(V8Proxy::GetDOMWrapperType(object) ==
+ V8ClassIndex::WORKER);
+ v8::Local<v8::Value> cache =
+ object->GetInternalField(V8Custom::kWorkerRequestCacheIndex);
+ if (cache->IsNull() || cache->IsUndefined()) {
+ cache = v8::Array::New();
+ object->SetInternalField(V8Custom::kWorkerRequestCacheIndex, cache);
+ }
+
+ v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
+ cache_array->Set(v8::Integer::New(cache_array->Length()), value);
+}
+
+static void RemoveHiddenDependency(v8::Local<v8::Object> object,
+ v8::Local<v8::Value> value) {
+ ASSERT(V8Proxy::GetDOMWrapperType(object) == V8ClassIndex::WORKER);
+ v8::Local<v8::Value> cache =
+ object->GetInternalField(V8Custom::kWorkerRequestCacheIndex);
+ ASSERT(cache->IsArray());
+ v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
+ for (int i = cache_array->Length() - 1; i >= 0; i--) {
+ v8::Local<v8::Value> cached = cache_array->Get(v8::Integer::New(i));
+ if (cached->StrictEquals(value)) {
+ cache_array->Delete(i);
+ return;
+ }
+ }
+
+ // We should only get here if we try to remove an event listener that was
+ // never added.
+}
+
+ACCESSOR_GETTER(WorkerOnmessage) {
+ INC_STATS(L"DOM.Worker.onmessage._get");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, info.Holder());
+ if (imp->onmessage()) {
+ V8ObjectEventListener* listener =
+ static_cast<V8ObjectEventListener*>(imp->onmessage());
+ v8::Local<v8::Object> v8_listener = listener->getListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(WorkerOnmessage) {
+ INC_STATS(L"DOM.Worker.onmessage._set");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, info.Holder());
+ V8ObjectEventListener* old_listener =
+ static_cast<V8ObjectEventListener*>(imp->onmessage());
+ if (value->IsNull()) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener = old_listener->getListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnmessage(0);
+
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener =
+ old_listener->getListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ imp->setOnmessage(listener);
+ CreateHiddenDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(WorkerOnerror) {
+ INC_STATS(L"DOM.Worker.onerror._get");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, info.Holder());
+ if (imp->onerror()) {
+ V8ObjectEventListener* listener =
+ static_cast<V8ObjectEventListener*>(imp->onerror());
+ v8::Local<v8::Object> v8_listener = listener->getListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(WorkerOnerror) {
+ INC_STATS(L"DOM.Worker.onerror._set");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, info.Holder());
+ V8ObjectEventListener* old_listener =
+ static_cast<V8ObjectEventListener*>(imp->onerror());
+ if (value->IsNull()) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener =
+ old_listener->getListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnerror(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener = old_listener->getListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ imp->setOnerror(listener);
+ CreateHiddenDependency(info.Holder(), value);
+ }
+ }
+}
+
+CALLBACK_FUNC_DECL(WorkerAddEventListener) {
+ INC_STATS(L"DOM.Worker.addEventListener()");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(args[1], false);
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->addEventListener(type, listener, useCapture);
+
+ CreateHiddenDependency(args.Holder(), args[1]);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WorkerRemoveEventListener) {
+ INC_STATS(L"DOM.Worker.removeEventListener()");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined(); // probably leaked
+
+ RefPtr<EventListener> listener =
+ proxy->FindObjectEventListener(args[1], false);
+
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->removeEventListener(type, listener.get(), useCapture);
+
+ RemoveHiddenDependency(args.Holder(), args[1]);
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/V8Binding/v8/dom_wrapper_map.h b/V8Binding/v8/dom_wrapper_map.h
new file mode 100644
index 0000000..e95ff88
--- /dev/null
+++ b/V8Binding/v8/dom_wrapper_map.h
@@ -0,0 +1,72 @@
+// 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 BINDINGS_V8_DOM_WRAPPER_MAP
+#define BINDINGS_V8_DOM_WRAPPER_MAP
+
+#include <v8.h>
+#include <wtf/HashMap.h>
+
+// A table of wrappers with weak pointers.
+// This table allows us to avoid track wrapped objects for debugging
+// and for ensuring that we don't double wrap the same object.
+template<class KeyType, class ValueType>
+class WeakReferenceMap {
+ public:
+ WeakReferenceMap(v8::WeakReferenceCallback callback) :
+ weak_reference_callback_(callback) { }
+#ifndef NDEBUG
+ virtual ~WeakReferenceMap() {
+ if (map_.size() > 0) {
+ fprintf(stderr, "Leak %d JS wrappers.\n", map_.size());
+ // Print out details.
+ }
+ }
+#endif
+
+ // Get the JS wrapper object of an object.
+ virtual v8::Persistent<ValueType> get(KeyType* obj) {
+ ValueType* wrapper = map_.get(obj);
+ return wrapper ? v8::Persistent<ValueType>(wrapper)
+ : v8::Persistent<ValueType>();
+ }
+
+ virtual void set(KeyType* obj, v8::Persistent<ValueType> wrapper) {
+ ASSERT(!map_.contains(obj));
+ wrapper.MakeWeak(obj, weak_reference_callback_);
+ map_.set(obj, *wrapper);
+ }
+
+ virtual void forget(KeyType* obj) {
+ ASSERT(obj);
+ ValueType* wrapper = map_.take(obj);
+ if (wrapper) {
+ v8::Persistent<ValueType> handle(wrapper);
+ handle.Dispose();
+ handle.Clear();
+ }
+ }
+
+ bool contains(KeyType* obj) {
+ return map_.contains(obj);
+ }
+
+ HashMap<KeyType*, ValueType*>& impl() {
+ return map_;
+ }
+
+ protected:
+ HashMap<KeyType*, ValueType*> map_;
+ v8::WeakReferenceCallback weak_reference_callback_;
+};
+
+
+template <class KeyType>
+class DOMWrapperMap : public WeakReferenceMap<KeyType, v8::Object> {
+ public:
+ DOMWrapperMap(v8::WeakReferenceCallback callback) :
+ WeakReferenceMap<KeyType, v8::Object>(callback) { }
+};
+
+#endif // BINDINGS_V8_DOM_WRAPPER_MAP
diff --git a/V8Binding/v8/npruntime.cpp b/V8Binding/v8/npruntime.cpp
new file mode 100644
index 0000000..d1138ab
--- /dev/null
+++ b/V8Binding/v8/npruntime.cpp
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <v8.h>
+
+#include "NPV8Object.h"
+#include "npruntime_priv.h"
+#include "V8NPObject.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+
+#include <utility>
+
+using namespace v8;
+
+
+// FIXME: Consider removing locks if we're singlethreaded already.
+// The static initializer here should work okay, but we want to avoid
+// static initialization in general.
+//
+// Commenting out the locks to avoid dependencies on chrome for now.
+// Need a platform abstraction which we can use.
+// static Lock StringIdentifierMapLock;
+
+
+// We use StringKey here as the key-type to avoid a string copy to
+// construct the map key and for faster comparisons than strcmp.
+struct StringKey {
+ StringKey() : string(NULL), length(0) {}
+ StringKey(const char* str) : string(str), length(strlen(str)) {}
+ const char* string;
+ size_t length;
+
+ StringKey& operator=(const StringKey& other) {
+ this->string = other.string;
+ this->length = other.length;
+ return *this;
+ }
+
+};
+
+inline bool operator==(const StringKey& x, const StringKey& y) {
+ // Shorter strings are less than longer strings, memcmp breaks ties.
+ if (x.length != y.length) {
+ return false;
+ } else {
+ ASSERT(x.string != NULL && y.string != NULL);
+ return memcmp(x.string, y.string, y.length) == 0;
+ }
+}
+
+struct StringKeyHash {
+ static unsigned hash(StringKey key) {
+ // sdbm hash function
+ unsigned hash = 0;
+ for (size_t i = 0; i < key.length; i++) {
+ char c = key.string[i];
+
+ hash += c;
+ hash += (hash << 10);
+ hash ^= (hash>> 6);
+ }
+
+ //
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+ if (hash == 0) {
+ hash = 27;
+ }
+ return hash;
+ }
+
+ static bool equal(StringKey x, StringKey y) {
+ return x == y;
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+namespace WTF {
+ template<> struct HashTraits<StringKey> : GenericHashTraits<StringKey> {
+ static const bool emptyValueIsZero = true;
+ static const bool needsDestruction = false;
+ static void constructDeletedValue(StringKey& slot) {
+ slot.string = NULL;
+ slot.length = 0;
+ }
+
+ static bool isDeletedValue(const StringKey& slot) {
+ return slot.string == NULL;
+ }
+ };
+}
+
+typedef WTF::HashMap<StringKey, PrivateIdentifier*, StringKeyHash> StringIdentifierMap;
+
+static StringIdentifierMap* getStringIdentifierMap() {
+ static StringIdentifierMap* stringIdentifierMap = 0;
+ if (!stringIdentifierMap)
+ stringIdentifierMap = new StringIdentifierMap();
+ return stringIdentifierMap;
+}
+
+// FIXME: Consider removing locks if we're singlethreaded already.
+// static Lock IntIdentifierMapLock;
+
+typedef WTF::HashMap<int, PrivateIdentifier*> IntIdentifierMap;
+
+static IntIdentifierMap* getIntIdentifierMap() {
+ static IntIdentifierMap* intIdentifierMap = 0;
+ if (!intIdentifierMap)
+ intIdentifierMap = new IntIdentifierMap();
+ return intIdentifierMap;
+}
+
+extern "C" {
+
+NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name) {
+ ASSERT(name);
+
+ if (name) {
+ // AutoLock safeLock(StringIdentifierMapLock);
+ StringKey key(name);
+ StringIdentifierMap* identMap = getStringIdentifierMap();
+ StringIdentifierMap::iterator iter = identMap->find(key);
+ if (iter != identMap->end())
+ return static_cast<NPIdentifier>(iter->second);
+
+ size_t nameLen = key.length;
+
+ // We never release identifiers, so this dictionary will grow.
+ PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(
+ malloc(sizeof(PrivateIdentifier) + nameLen + 1));
+ char* nameStorage = reinterpret_cast<char*>(identifier + 1);
+ memcpy(nameStorage, name, nameLen + 1);
+ identifier->isString = true;
+ identifier->value.string = reinterpret_cast<NPUTF8*>(nameStorage);
+ key.string = nameStorage;
+ identMap->set(key, identifier);
+ return (NPIdentifier)identifier;
+ }
+
+ return 0;
+}
+
+void NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount,
+ NPIdentifier* identifiers) {
+ ASSERT(names);
+ ASSERT(identifiers);
+
+ if (names && identifiers)
+ for (int i = 0; i < nameCount; i++)
+ identifiers[i] = NPN_GetStringIdentifier(names[i]);
+}
+
+NPIdentifier NPN_GetIntIdentifier(int32_t intid) {
+ // AutoLock safeLock(IntIdentifierMapLock);
+
+ IntIdentifierMap* identMap = getIntIdentifierMap();
+ IntIdentifierMap::iterator iter = identMap->find(intid);
+ if (iter != identMap->end())
+ return static_cast<NPIdentifier>(iter->second);
+
+ // We never release identifiers, so this dictionary will grow.
+ PrivateIdentifier* identifier = reinterpret_cast<PrivateIdentifier*>(
+ malloc(sizeof(PrivateIdentifier)));
+ identifier->isString = false;
+ identifier->value.number = intid;
+ identMap->set(intid, identifier);
+ return (NPIdentifier)identifier;
+}
+
+bool NPN_IdentifierIsString(NPIdentifier identifier) {
+ PrivateIdentifier* i = reinterpret_cast<PrivateIdentifier*>(identifier);
+ return i->isString;
+}
+
+NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) {
+ PrivateIdentifier* i = reinterpret_cast<PrivateIdentifier*>(identifier);
+ if (!i->isString || !i->value.string)
+ return NULL;
+
+ return (NPUTF8 *)strdup(i->value.string);
+}
+
+int32_t NPN_IntFromIdentifier(NPIdentifier identifier) {
+ PrivateIdentifier* i = reinterpret_cast<PrivateIdentifier*>(identifier);
+ if (i->isString)
+ return 0;
+ return i->value.number;
+}
+
+void NPN_ReleaseVariantValue(NPVariant* variant) {
+ ASSERT(variant);
+
+ if (variant->type == NPVariantType_Object) {
+ NPN_ReleaseObject(variant->value.objectValue);
+ variant->value.objectValue = 0;
+ } else if (variant->type == NPVariantType_String) {
+ free((void*)variant->value.stringValue.UTF8Characters);
+ variant->value.stringValue.UTF8Characters = 0;
+ variant->value.stringValue.UTF8Length = 0;
+ }
+
+ variant->type = NPVariantType_Void;
+}
+
+NPObject *NPN_CreateObject(NPP npp, NPClass* aClass) {
+ ASSERT(aClass);
+
+ if (aClass) {
+ NPObject* obj;
+ if (aClass->allocate != NULL)
+ obj = aClass->allocate(npp, aClass);
+ else
+ obj = reinterpret_cast<NPObject*>(malloc(sizeof(NPObject)));
+
+ obj->_class = aClass;
+ obj->referenceCount = 1;
+ return obj;
+ }
+
+ return 0;
+}
+
+NPObject* NPN_RetainObject(NPObject* obj) {
+ ASSERT(obj);
+ ASSERT(obj->referenceCount > 0);
+
+ if (obj)
+ obj->referenceCount++;
+
+ return obj;
+}
+
+// _NPN_DeallocateObject actually deletes the object. Technically,
+// callers should use NPN_ReleaseObject. Webkit exposes this function
+// to kill objects which plugins may not have properly released.
+void _NPN_DeallocateObject(NPObject *obj) {
+ ASSERT(obj);
+ ASSERT(obj->referenceCount >= 0);
+
+ if (obj) {
+ // NPObjects that remain in pure C++ may never have wrappers.
+ // Hence, if it's not already alive, don't unregister it.
+ // If it is alive, unregister it as the *last* thing we do
+ // so that it can do as much cleanup as possible on its own.
+ if (_NPN_IsAlive(obj))
+ _NPN_UnregisterObject(obj);
+
+ obj->referenceCount = -1;
+ if (obj->_class->deallocate)
+ obj->_class->deallocate(obj);
+ else
+ free(obj);
+ }
+}
+
+void NPN_ReleaseObject(NPObject* obj) {
+ ASSERT(obj);
+ ASSERT(obj->referenceCount >= 1);
+
+ if (obj && obj->referenceCount >= 1) {
+ if (--obj->referenceCount == 0)
+ _NPN_DeallocateObject(obj);
+ }
+}
+
+void _NPN_InitializeVariantWithStringCopy(NPVariant* variant,
+ const NPString* value) {
+ variant->type = NPVariantType_String;
+ variant->value.stringValue.UTF8Length = value->UTF8Length;
+ variant->value.stringValue.UTF8Characters =
+ reinterpret_cast<NPUTF8*>(malloc(sizeof(NPUTF8) * value->UTF8Length));
+ memcpy((void*)variant->value.stringValue.UTF8Characters,
+ value->UTF8Characters,
+ sizeof(NPUTF8) * value->UTF8Length);
+}
+
+
+// NPN_Registry
+//
+// The registry is designed for quick lookup of NPObjects.
+// JS needs to be able to quickly lookup a given NPObject to determine
+// if it is alive or not.
+// The browser needs to be able to quickly lookup all NPObjects which are
+// "owned" by an object.
+//
+// The g_live_objects is a hash table of all live objects to their owner
+// objects. Presence in this table is used primarily to determine if
+// objects are live or not.
+//
+// The g_root_objects is a hash table of root objects to a set of
+// objects that should be deactivated in sync with the root. A
+// root is defined as a top-level owner object. This is used on
+// Frame teardown to deactivate all objects associated
+// with a particular plugin.
+
+typedef WTF::HashSet<NPObject*> NPObjectSet;
+typedef WTF::HashMap<NPObject*, NPObject*> NPObjectMap;
+typedef WTF::HashMap<NPObject*, NPObjectSet*> NPRootObjectMap;
+
+// A map of live NPObjects with pointers to their Roots.
+NPObjectMap g_live_objects;
+
+// A map of the root objects and the list of NPObjects
+// associated with that object.
+NPRootObjectMap g_root_objects;
+
+void _NPN_RegisterObject(NPObject* obj, NPObject* owner) {
+ ASSERT(obj);
+
+ // Check if already registered.
+ if (g_live_objects.find(obj) != g_live_objects.end()) {
+ return;
+ }
+
+ if (!owner) {
+ // Registering a new owner object.
+ ASSERT(g_root_objects.find(obj) == g_root_objects.end());
+ g_root_objects.set(obj, new NPObjectSet());
+ } else {
+ // Always associate this object with it's top-most parent.
+ // Since we always flatten, we only have to look up one level.
+ NPObjectMap::iterator owner_entry = g_live_objects.find(owner);
+ NPObject* parent = NULL;
+ if (g_live_objects.end() != owner_entry)
+ parent = owner_entry->second;
+
+ if (parent) {
+ owner = parent;
+ }
+ ASSERT(g_root_objects.find(obj) == g_root_objects.end());
+ if (g_root_objects.find(owner) != g_root_objects.end())
+ g_root_objects.get(owner)->add(obj);
+ }
+
+ ASSERT(g_live_objects.find(obj) == g_live_objects.end());
+ g_live_objects.set(obj, owner);
+}
+
+void _NPN_UnregisterObject(NPObject* obj) {
+ ASSERT(obj);
+ ASSERT(g_live_objects.find(obj) != g_live_objects.end());
+
+ NPObject* owner = NULL;
+ if (g_live_objects.find(obj) != g_live_objects.end())
+ owner = g_live_objects.find(obj)->second;
+
+ if (owner == NULL) {
+ // Unregistering a owner object; also unregister it's descendants.
+ ASSERT(g_root_objects.find(obj) != g_root_objects.end());
+ NPObjectSet* set = g_root_objects.get(obj);
+ while (set->size() > 0) {
+#ifndef NDEBUG
+ size_t size = set->size();
+#endif
+ NPObject* sub_object = *(set->begin());
+ // The sub-object should not be a owner!
+ ASSERT(g_root_objects.find(sub_object) == g_root_objects.end());
+
+ // First, unregister the object.
+ set->remove(sub_object);
+ g_live_objects.remove(sub_object);
+
+ // Remove the JS references to the object.
+ ForgetV8ObjectForNPObject(sub_object);
+
+ ASSERT(set->size() < size);
+ }
+ delete set;
+ g_root_objects.remove(obj);
+ } else {
+ NPRootObjectMap::iterator owner_entry = g_root_objects.find(owner);
+ if (owner_entry != g_root_objects.end()) {
+ NPObjectSet* list = owner_entry->second;
+ ASSERT(list->find(obj) != list->end());
+ list->remove(obj);
+ }
+ }
+ ForgetV8ObjectForNPObject(obj);
+
+ g_live_objects.remove(obj);
+}
+
+bool _NPN_IsAlive(NPObject* obj) {
+ return g_live_objects.find(obj) != g_live_objects.end();
+}
+
+} // extern "C"
diff --git a/V8Binding/v8/npruntime_impl.h b/V8Binding/v8/npruntime_impl.h
new file mode 100644
index 0000000..31db922
--- /dev/null
+++ b/V8Binding/v8/npruntime_impl.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef npruntime_impl_h
+#define npruntime_impl_h
+
+#if PLATFORM(CHROMIUM)
+#include "bindings/npruntime.h"
+#else
+#include "npruntime.h" // use V8Binding/npapi version
+#endif
+
+// This file exists to support WebCore, which expects to be able to call upon
+// portions of the NPRuntime implementation.
+
+// A simple mapping for now. FIXME We should probably just adopt the
+// underscore prefix as our naming convention too.
+
+#define _NPN_ReleaseVariantValue NPN_ReleaseVariantValue
+#define _NPN_GetStringIdentifier NPN_GetStringIdentifier
+#define _NPN_GetStringIdentifiers NPN_GetStringIdentifiers
+#define _NPN_GetIntIdentifier NPN_GetIntIdentifier
+#define _NPN_IdentifierIsString NPN_IdentifierIsString
+#define _NPN_UTF8FromIdentifier NPN_UTF8FromIdentifier
+#define _NPN_IntFromIdentifier NPN_IntFromIdentifier
+#define _NPN_CreateObject NPN_CreateObject
+#define _NPN_RetainObject NPN_RetainObject
+#define _NPN_ReleaseObject NPN_ReleaseObject
+#define _NPN_DeallocateObject NPN_DeallocateObject
+#define _NPN_Invoke NPN_Invoke
+#define _NPN_InvokeDefault NPN_InvokeDefault
+#define _NPN_Evaluate NPN_Evaluate
+#define _NPN_GetProperty NPN_GetProperty
+#define _NPN_SetProperty NPN_SetProperty
+#define _NPN_RemoveProperty NPN_RemoveProperty
+#define _NPN_HasProperty NPN_HasProperty
+#define _NPN_HasMethod NPN_HasMethod
+#define _NPN_SetException NPN_SetException
+#define _NPN_Enumerate NPN_Enumerate
+#define _NPN_Construct NPN_Construct
+
+#endif
diff --git a/V8Binding/v8/npruntime_internal.h b/V8Binding/v8/npruntime_internal.h
new file mode 100644
index 0000000..75bf2b0
--- /dev/null
+++ b/V8Binding/v8/npruntime_internal.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007 Collabora, Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This is a internal include header for npapi.h
+ *
+ * Some of the #defines which are in X11 headers conflict with type and enum
+ * names in JavaScriptCore and WebCore
+ * This header #undefs those defines to fix the conflicts
+ * If you need to include npapi.h or npruntime.h when building on X11,
+ * include this file instead of the actual npapi.h or npruntime.h
+ */
+
+#include "npapi.h"
+#include "npruntime.h"
+#include "npfunctions.h"
+
+#ifdef XP_UNIX
+ #include <X11/Xresource.h>
+
+ #undef None
+ #undef Above
+ #undef Below
+ #undef Auto
+ #undef Complex
+ #undef Status
+#endif
diff --git a/V8Binding/v8/npruntime_priv.h b/V8Binding/v8/npruntime_priv.h
new file mode 100644
index 0000000..8b1ddec
--- /dev/null
+++ b/V8Binding/v8/npruntime_priv.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NP_RUNTIME_PRIV_H_
+#define NP_RUNTIME_PRIV_H_
+
+#if PLATFORM(CHROMIUM)
+#include "third_party/npapi/bindings/npruntime.h"
+#else
+#include "bridge/npruntime.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ _NPN_InitializeVariantWithStringCopy() will copy string data. The string data
+ will be deallocated by calls to NPReleaseVariantValue().
+*/
+void _NPN_InitializeVariantWithStringCopy(NPVariant*, const NPString*);
+void _NPN_DeallocateObject(NPObject *obj);
+
+// The following routines allow the browser to aggressively cleanup NPObjects
+// on a per plugin basis. All NPObjects used through the NPRuntime API should
+// be "registered" while they are alive. After an object has been
+// deleted, it is possible for Javascript to have a reference to that object
+// which has not yet been garbage collected. Javascript access to NPObjects
+// will reference this registry to determine if the object is accessible or
+// not.
+
+// Windows introduces an additional complication for objects created by the
+// plugin. Plugins load inside of a DLL. Each DLL has it's own heap. If
+// the browser unloads the plugin DLL, all objects created within the DLL's
+// heap instantly become invalid. Normally, when WebKit drops the reference
+// on the top-level plugin object, it tells the plugin manager that the
+// plugin can be destroyed, which can unload the DLL. So, we must eliminate
+// all pointers to any object ever created by the plugin.
+
+// We generally associate NPObjects with an owner. The owner of an NPObject
+// is an NPObject which, when destroyed, also destroys all objects it owns.
+// For example, if an NPAPI plugin creates 10 sub-NPObjects, all 11 objects
+// (the NPAPI plugin + its 10 sub-objects) should become inaccessible
+// simultaneously.
+
+// The ownership hierarchy is flat, and not a tree. Imagine the following
+// object creation:
+// PluginObject
+// |
+// +-- Creates -----> Object1
+// |
+// +-- Creates -----> Object2
+//
+// PluginObject will be the "owner" for both Object1 and Object2.
+
+// Register an NPObject with the runtime. If the owner is NULL, the
+// object is treated as an owning object. If owner is not NULL,
+// this object will be registered as owned by owner's top-level owner.
+void _NPN_RegisterObject(NPObject* obj, NPObject* owner);
+
+// Unregister an NPObject with the runtime. If obj is an owning
+// object, this call will also unregister all of the owned objects.
+void _NPN_UnregisterObject(NPObject* obj);
+
+// Check to see if an object is registered with the runtime.
+// Return true if registered, false otherwise.
+bool _NPN_IsAlive(NPObject* obj);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif
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
diff --git a/V8Binding/v8/v8_binding.h b/V8Binding/v8/v8_binding.h
new file mode 100644
index 0000000..8300dd7
--- /dev/null
+++ b/V8Binding/v8/v8_binding.h
@@ -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.
+
+#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);
+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);
+}
+
+// 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__
diff --git a/V8Binding/v8/v8_custom.cpp b/V8Binding/v8/v8_custom.cpp
new file mode 100644
index 0000000..855e192
--- /dev/null
+++ b/V8Binding/v8/v8_custom.cpp
@@ -0,0 +1,1102 @@
+/*
+ * Copyright (C) 2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2004-2006 Apple Computer, Inc.
+ * Copyright (C) 2006 James G. Speth (speth@end.com)
+ * Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
+ * Copyright 2007, 2008 Google Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <Assertions.h>
+#include <wtf/ASCIICType.h>
+
+#include "v8_proxy.h"
+#include "v8_binding.h"
+#include "V8NPObject.h"
+#include "v8_custom.h"
+
+#include "V8Attr.h"
+#include "V8CanvasGradient.h"
+#include "V8CanvasPattern.h"
+#include "V8CustomEventListener.h"
+#include "V8Document.h"
+#include "V8DOMWindow.h"
+#include "V8HTMLCanvasElement.h"
+#include "V8HTMLDocument.h"
+#include "V8HTMLImageElement.h"
+#include "V8HTMLOptionElement.h"
+#include "V8Node.h"
+
+#if ENABLE(XPATH)
+#include "V8XPathNSResolver.h"
+#include "V8XPathResult.h"
+#endif
+
+#include "Base64.h"
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "CanvasRenderingContext2D.h"
+#include "CanvasStyle.h"
+#include "Clipboard.h"
+#include "ClipboardEvent.h"
+#include "Console.h"
+#include "DOMParser.h"
+#include "DOMStringList.h"
+#include "DOMTimer.h"
+#include "DOMWindow.h"
+#include "Document.h"
+#include "DocumentFragment.h"
+#include "Event.h"
+#include "EventListener.h"
+#include "EventTarget.h"
+#include "ExceptionCode.h"
+#include "FloatRect.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "HTMLBodyElement.h"
+#include "HTMLCanvasElement.h"
+#include "HTMLDocument.h"
+#include "HTMLEmbedElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLFrameElement.h"
+#include "HTMLFrameElementBase.h"
+#include "HTMLFrameSetElement.h"
+#include "HTMLIFrameElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "HTMLOptionElement.h"
+#include "HTMLOptionsCollection.h"
+#include "HTMLSelectElement.h"
+#include "History.h"
+#include "JSXPathNSResolver.h"
+#include "JSDOMBinding.h"
+#include "KURL.h"
+#include "Location.h"
+#include "MessageChannel.h"
+#include "MessagePort.h"
+#include "MouseEvent.h"
+#include "NodeIterator.h"
+#include "NodeList.h"
+#include "RGBColor.h"
+#include "RenderPartObject.h"
+#include "RenderWidget.h"
+#include "ScheduledAction.h"
+#include "ScriptState.h"
+#include "ScriptController.h"
+#include "ScriptSourceCode.h"
+#include "SecurityOrigin.h"
+#include "StyleSheetList.h"
+#include "TreeWalker.h"
+#include "WebKitCSSMatrix.h"
+#include "WebKitPoint.h"
+#include "XMLSerializer.h"
+#include "XPathEvaluator.h"
+#include "XPathResult.h"
+#include "XSLTProcessor.h"
+
+#if ENABLE(SVG)
+#include "V8SVGPODTypeWrapper.h"
+#include "SVGElementInstance.h"
+#include "SVGException.h"
+#include "SVGPathSeg.h"
+#endif
+
+#include "Navigator.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebKitPointConstructor) {
+ INC_STATS("DOM.WebKitPoint.Constructor");
+ return V8Proxy::ConstructDOMObject<V8ClassIndex::WEBKITPOINT,
+ WebKitPoint>(args);
+}
+
+// DOMImplementation is a singleton in WebCore. If we use our normal
+// mapping from DOM objects to V8 wrappers, the same wrapper will be
+// shared for all frames in the same process. This is a major
+// security problem. Therefore, we generate a DOMImplementation
+// wrapper per document and store it in an internal field of the
+// document. Since the DOMImplementation object is a singleton, we do
+// not have to do anything to keep the DOMImplementation object alive
+// for the lifetime of the wrapper.
+ACCESSOR_GETTER(DocumentImplementation) {
+ ASSERT(info.Holder()->InternalFieldCount() >=
+ kDocumentMinimumInternalFieldCount);
+ // Check if the internal field already contains a wrapper.
+ v8::Local<v8::Value> implementation =
+ info.Holder()->GetInternalField(kDocumentImplementationIndex);
+ if (!implementation->IsUndefined()) {
+ return implementation;
+ }
+ // Generate a wrapper.
+ Document* doc = V8Proxy::DOMWrapperToNative<Document>(info.Holder());
+ v8::Handle<v8::Value> wrapper =
+ V8Proxy::DOMImplementationToV8Object(doc->implementation());
+ // Store the wrapper in the internal field.
+ info.Holder()->SetInternalField(kDocumentImplementationIndex, wrapper);
+
+ return wrapper;
+}
+
+
+ACCESSOR_GETTER(DocumentLocation) {
+ Document* imp = V8Proxy::DOMWrapperToNative<Document>(info.Holder());
+ if (!imp->frame())
+ return v8::Null();
+
+ DOMWindow* window = imp->frame()->domWindow();
+ return V8Proxy::ToV8Object(V8ClassIndex::LOCATION, window->location());
+}
+
+
+ACCESSOR_SETTER(DocumentLocation) {
+ Document* imp = V8Proxy::DOMWrapperToNative<Document>(info.Holder());
+ if (!imp->frame())
+ return;
+
+ DOMWindow* window = imp->frame()->domWindow();
+ // WindowSetLocation does security checks. // XXXMB- verify!
+ WindowSetLocation(window, ToWebCoreString(value));
+}
+
+
+INDEXED_PROPERTY_GETTER(HTMLFormElement) {
+ INC_STATS("DOM.HTMLFormElement.IndexedPropertyGetter");
+ HTMLFormElement* form =
+ V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder());
+
+ RefPtr<Node> result = form->elements()->item(index);
+ if (!result) return v8::Handle<v8::Value>();
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+
+INDEXED_PROPERTY_GETTER(HTMLOptionsCollection) {
+ INC_STATS("DOM.HTMLOptionsCollection.IndexedPropertyGetter");
+ HTMLOptionsCollection* collection =
+ V8Proxy::ToNativeObject<HTMLOptionsCollection>(
+ V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
+
+ RefPtr<Node> result = collection->item(index);
+ if (!result) return v8::Handle<v8::Value>();
+
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+static v8::Handle<v8::Value> OptionsCollectionSetter(uint32_t index,
+ v8::Handle<v8::Value> value, HTMLSelectElement* base) {
+ if (value->IsNull() || value->IsUndefined()) {
+ base->remove(index);
+ return value;
+ }
+
+ ExceptionCode ec = 0;
+
+ // Check that the value is an HTMLOptionElement. If not, throw a
+ // TYPE_MISMATCH_ERR DOMException.
+ if (!V8HTMLOptionElement::HasInstance(value)) {
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return value;
+ }
+
+ HTMLOptionElement* element =
+ V8Proxy::DOMWrapperToNode<HTMLOptionElement>(
+ v8::Handle<v8::Object>::Cast(value));
+ base->setOption(index, element, ec);
+
+ V8Proxy::SetDOMException(ec);
+ return value;
+}
+
+
+INDEXED_PROPERTY_SETTER(HTMLOptionsCollection) {
+ INC_STATS("DOM.HTMLOptionsCollection.IndexedPropertySetter");
+ HTMLOptionsCollection* collection =
+ V8Proxy::ToNativeObject<HTMLOptionsCollection>(
+ V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
+ HTMLSelectElement* base = static_cast<HTMLSelectElement*>(collection->base());
+ return OptionsCollectionSetter(index, value, base);
+}
+
+
+INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection) {
+ INC_STATS("DOM.HTMLSelectElementCollection.IndexedPropertySetter");
+ HTMLSelectElement* select =
+ V8Proxy::DOMWrapperToNode<HTMLSelectElement>(info.Holder());
+ return OptionsCollectionSetter(index, value, select);
+}
+
+// CanvasRenderingContext2D ----------------------------------------------------
+
+// Helper macro for converting v8 values into floats (expected by many of the
+// canvas functions).
+#define TO_FLOAT(a) static_cast<float>((a)->NumberValue())
+
+// TODO: SetStrokeColor and SetFillColor are similar except function names,
+// consolidate them into one.
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetStrokeColor) {
+ INC_STATS("DOM.CanvasRenderingContext2D.setStrokeColor()");
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ switch (args.Length()) {
+ case 1:
+ if (args[0]->IsString()) {
+ context->setStrokeColor(ToWebCoreString(args[0]));
+ } else {
+ context->setStrokeColor(TO_FLOAT(args[0]));
+ }
+ break;
+ case 2:
+ if (args[0]->IsString()) {
+ context->setStrokeColor(ToWebCoreString(args[0]),
+ TO_FLOAT(args[1]));
+ } else {
+ context->setStrokeColor(TO_FLOAT(args[0]),
+ TO_FLOAT(args[1]));
+ }
+ break;
+ case 4:
+ context->setStrokeColor(TO_FLOAT(args[0]),
+ TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]));
+ break;
+ case 5:
+ context->setStrokeColor(TO_FLOAT(args[0]),
+ TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]),
+ TO_FLOAT(args[4]));
+ break;
+ default:
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR,
+ "setStrokeColor: Invalid number of arguments");
+ break;
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetFillColor) {
+ INC_STATS("DOM.CanvasRenderingContext2D.setFillColor()");
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ switch (args.Length()) {
+ case 1:
+ if (args[0]->IsString()) {
+ context->setFillColor(ToWebCoreString(args[0]));
+ } else {
+ context->setFillColor(TO_FLOAT(args[0]));
+ }
+ break;
+ case 2:
+ if (args[0]->IsString()) {
+ context->setFillColor(ToWebCoreString(args[0]), TO_FLOAT(args[1]));
+ } else {
+ context->setFillColor(TO_FLOAT(args[0]), TO_FLOAT(args[1]));
+ }
+ break;
+ case 4:
+ context->setFillColor(TO_FLOAT(args[0]),
+ TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]));
+ break;
+ case 5:
+ context->setFillColor(TO_FLOAT(args[0]),
+ TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]),
+ TO_FLOAT(args[4]));
+ break;
+ default:
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR,
+ "setFillColor: Invalid number of arguments");
+ break;
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeRect) {
+ INC_STATS("DOM.CanvasRenderingContext2D.strokeRect()");
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ if (args.Length() == 5) {
+ context->strokeRect(TO_FLOAT(args[0]),
+ TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]),
+ TO_FLOAT(args[4]));
+ } else if (args.Length() == 4) {
+ context->strokeRect(TO_FLOAT(args[0]),
+ TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]));
+ } else {
+ V8Proxy::SetDOMException(INDEX_SIZE_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetShadow) {
+ INC_STATS("DOM.CanvasRenderingContext2D.setShadow()");
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+
+ switch (args.Length()) {
+ case 3:
+ context->setShadow(TO_FLOAT(args[0]), TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]));
+ break;
+ case 4:
+ if (args[3]->IsString())
+ context->setShadow(TO_FLOAT(args[0]), TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]), ToWebCoreString(args[3]));
+ else
+ context->setShadow(TO_FLOAT(args[0]), TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]), TO_FLOAT(args[3]));
+ break;
+ case 5:
+ if (args[3]->IsString())
+ context->setShadow(TO_FLOAT(args[0]), TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]), ToWebCoreString(args[3]),
+ TO_FLOAT(args[4]));
+ else
+ context->setShadow(TO_FLOAT(args[0]), TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]), TO_FLOAT(args[3]),
+ TO_FLOAT(args[4]));
+ break;
+ case 7:
+ context->setShadow(TO_FLOAT(args[0]), TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]), TO_FLOAT(args[3]),
+ TO_FLOAT(args[4]), TO_FLOAT(args[5]),
+ TO_FLOAT(args[6]));
+ break;
+ case 8:
+ context->setShadow(TO_FLOAT(args[0]), TO_FLOAT(args[1]),
+ TO_FLOAT(args[2]), TO_FLOAT(args[3]),
+ TO_FLOAT(args[4]), TO_FLOAT(args[5]),
+ TO_FLOAT(args[6]), TO_FLOAT(args[7]));
+ break;
+ default:
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR,
+ "setShadow: Invalid number of arguments");
+ break;
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage) {
+ INC_STATS("DOM.CanvasRenderingContext2D.drawImage()");
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+
+ v8::Handle<v8::Value> arg = args[0];
+
+ if (V8HTMLImageElement::HasInstance(arg)) {
+ ExceptionCode ec = 0;
+ HTMLImageElement* image_element =
+ V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg);
+ switch (args.Length()) {
+ case 3:
+ context->drawImage(image_element, TO_FLOAT(args[1]), TO_FLOAT(args[2]));
+ break;
+ case 5:
+ context->drawImage(image_element, TO_FLOAT(args[1]), TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]), TO_FLOAT(args[4]), ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ break;
+ case 9:
+ context->drawImage(image_element,
+ FloatRect(TO_FLOAT(args[1]), TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]), TO_FLOAT(args[4])),
+ FloatRect(TO_FLOAT(args[5]), TO_FLOAT(args[6]),
+ TO_FLOAT(args[7]), TO_FLOAT(args[8])),
+ ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ break;
+ default:
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR,
+ "drawImage: Invalid number of arguments");
+ return v8::Undefined();
+ }
+ return v8::Undefined();
+ }
+
+ // HTMLCanvasElement
+ if (V8HTMLCanvasElement::HasInstance(arg)) {
+ ExceptionCode ec = 0;
+ HTMLCanvasElement* canvas_element =
+ V8Proxy::DOMWrapperToNode<HTMLCanvasElement>(arg);
+ switch (args.Length()) {
+ case 3:
+ context->drawImage(canvas_element, TO_FLOAT(args[1]), TO_FLOAT(args[2]));
+ break;
+ case 5:
+ context->drawImage(canvas_element, TO_FLOAT(args[1]), TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]), TO_FLOAT(args[4]), ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ break;
+ case 9:
+ context->drawImage(canvas_element,
+ FloatRect(TO_FLOAT(args[1]), TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]), TO_FLOAT(args[4])),
+ FloatRect(TO_FLOAT(args[5]), TO_FLOAT(args[6]),
+ TO_FLOAT(args[7]), TO_FLOAT(args[8])),
+ ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ break;
+ default:
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR,
+ "drawImage: Invalid number of arguments");
+ return v8::Undefined();
+ }
+ return v8::Undefined();
+ }
+
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Handle<v8::Value>();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImageFromRect) {
+ INC_STATS("DOM.CanvasRenderingContext2D.drawImageFromRect()");
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+
+ v8::Handle<v8::Value> arg = args[0];
+
+ if (V8HTMLImageElement::HasInstance(arg)) {
+ HTMLImageElement* image_element =
+ V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg);
+ context->drawImageFromRect(image_element,
+ TO_FLOAT(args[1]), TO_FLOAT(args[2]),
+ TO_FLOAT(args[3]), TO_FLOAT(args[4]),
+ TO_FLOAT(args[5]), TO_FLOAT(args[6]),
+ TO_FLOAT(args[7]), TO_FLOAT(args[8]),
+ ToWebCoreString(args[9]));
+ } else {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR,
+ "drawImageFromRect: Invalid type of arguments");
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DCreatePattern) {
+ INC_STATS("DOM.CanvasRenderingContext2D.createPattern()");
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+
+ v8::Handle<v8::Value> arg = args[0];
+
+ if (V8HTMLImageElement::HasInstance(arg)) {
+ HTMLImageElement* image_element =
+ V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg);
+ ExceptionCode ec = 0;
+ RefPtr<CanvasPattern> pattern =
+ context->createPattern(image_element, valueToStringWithNullCheck(args[1]), ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, pattern.get());
+ }
+
+ if (V8HTMLCanvasElement::HasInstance(arg)) {
+ HTMLCanvasElement* canvas_element =
+ V8Proxy::DOMWrapperToNode<HTMLCanvasElement>(arg);
+ ExceptionCode ec = 0;
+ RefPtr<CanvasPattern> pattern =
+ context->createPattern(canvas_element, valueToStringWithNullCheck(args[1]), ec);
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, pattern.get());
+ }
+
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Handle<v8::Value>();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DFillText) {
+ INC_STATS("DOM.CanvasRenderingContext2D.fillText()");
+
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+
+ // Two forms:
+ // * fillText(text, x, y)
+ // * fillText(text, x, y, maxWidth)
+ if (args.Length() < 3 || args.Length() > 4) {
+ V8Proxy::SetDOMException(SYNTAX_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
+ String text = ToWebCoreString(args[0]);
+ float x = TO_FLOAT(args[1]);
+ float y = TO_FLOAT(args[2]);
+
+ if (args.Length() == 4) {
+ float maxWidth = TO_FLOAT(args[3]);
+ context->fillText(text, x, y, maxWidth);
+ } else {
+ context->fillText(text, x, y);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeText) {
+ INC_STATS("DOM.CanvasRenderingContext2D.strokeText()");
+
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+
+ // Two forms:
+ // * strokeText(text, x, y)
+ // * strokeText(text, x, y, maxWidth)
+ if (args.Length() < 3 || args.Length() > 4) {
+ V8Proxy::SetDOMException(SYNTAX_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
+ String text = ToWebCoreString(args[0]);
+ float x = TO_FLOAT(args[1]);
+ float y = TO_FLOAT(args[2]);
+
+ if (args.Length() == 4) {
+ float maxWidth = TO_FLOAT(args[3]);
+ context->strokeText(text, x, y, maxWidth);
+ } else {
+ context->strokeText(text, x, y);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(CanvasRenderingContext2DPutImageData) {
+ INC_STATS("DOM.CanvasRenderingContext2D.putImageData()");
+
+ // Two froms:
+ // * putImageData(ImageData, x, y)
+ // * putImageData(ImageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight)
+ if (args.Length() != 3 && args.Length() != 7) {
+ V8Proxy::SetDOMException(SYNTAX_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
+ CanvasRenderingContext2D* context =
+ V8Proxy::ToNativeObject<CanvasRenderingContext2D>(
+ V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+
+ ImageData* imageData = 0;
+
+ // Need to check that the argument is of the correct type, since
+ // ToNativeObject() expects it to be correct. If the argument was incorrect
+ // we leave it null, and putImageData() will throw the correct exception
+ // (TYPE_MISMATCH_ERR).
+ if (V8Proxy::IsWrapperOfType(args[0], V8ClassIndex::IMAGEDATA)) {
+ imageData = V8Proxy::ToNativeObject<ImageData>(
+ V8ClassIndex::IMAGEDATA, args[0]);
+ }
+
+ ExceptionCode ec = 0;
+
+ if (args.Length() == 7) {
+ context->putImageData(imageData,
+ TO_FLOAT(args[1]), TO_FLOAT(args[2]), TO_FLOAT(args[3]),
+ TO_FLOAT(args[4]), TO_FLOAT(args[5]), TO_FLOAT(args[6]), ec);
+ } else {
+ context->putImageData(imageData, TO_FLOAT(args[1]), TO_FLOAT(args[2]), ec);
+ }
+
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return v8::Undefined();
+}
+
+static bool AllowSettingSrcToJavascriptURL(Element* element, String name,
+ String value) {
+ // Need to parse value as URL first in order to check its protocol.
+ // " javascript:", "java\0script:", "javascript\t:", "javascript\1:"
+ // are all parsed as "javascript:" url.
+ // When changing location in HTMLFrameElement, value is parsed as url.
+ // We must match the behavior there.
+ // See issue 804099.
+ //
+ // parseURL is defined in CSSHelper.cpp.
+ if ((element->hasTagName(HTMLNames::iframeTag) ||
+ element->hasTagName(HTMLNames::frameTag)) &&
+ equalIgnoringCase(name, "src") &&
+ parseURL(value).startsWith("javascript:", false)) {
+ HTMLFrameElementBase* frame = static_cast<HTMLFrameElementBase*>(element);
+ Node* contentDoc = frame->contentDocument();
+ if (contentDoc && !V8Proxy::CheckNodeSecurity(contentDoc))
+ return false;
+ }
+ return true;
+}
+
+
+static bool AllowSettingFrameSrcToJavascriptUrl(HTMLFrameElementBase* frame,
+ String value) {
+ // See same issue in AllowSettingSrcToJavascriptURL.
+ if (parseURL(value).startsWith("javascript:", false)) {
+ Node* contentDoc = frame->contentDocument();
+ if (contentDoc && !V8Proxy::CheckNodeSecurity(contentDoc))
+ return false;
+ }
+ return true;
+}
+
+
+// HTMLIFrameElement -----------------------------------------------------------
+
+// TODO(mbelshe): This should move into V8DOMWindowCustom.cpp
+// Can't move it right now because it depends on V8ScheduledAction,
+// which is private to this file (v8_custom.cpp).
+v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args,
+ bool single_shot) {
+ int num_arguments = args.Length();
+
+ if (num_arguments < 1) return v8::Undefined();
+
+ DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(
+ V8ClassIndex::DOMWINDOW, args.Holder());
+
+ if (!imp->frame())
+ return v8::Undefined();
+
+ if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ return v8::Undefined();
+
+ ScriptExecutionContext* script_context =
+ static_cast<ScriptExecutionContext*>(imp->frame()->document());
+
+ v8::Handle<v8::Value> function = args[0];
+
+ int32_t timeout = 0;
+ if (num_arguments >= 2) timeout = args[1]->Int32Value();
+
+ int id;
+ if (function->IsString()) {
+ // Don't allow setting timeouts to run empty functions!
+ // (Bug 1009597)
+ WebCore::String string_function = ToWebCoreString(function);
+ if (string_function.length() == 0)
+ return v8::Undefined();
+
+ id = DOMTimer::install(script_context,
+ new ScheduledAction(string_function), timeout,
+ single_shot);
+ } else if (function->IsFunction()) {
+ int param_count = num_arguments >= 2 ? num_arguments - 2 : 0;
+ v8::Local<v8::Value>* params = 0;
+ if (param_count > 0) {
+ params = new v8::Local<v8::Value>[param_count];
+ for (int i = 0; i < param_count; i++)
+ // parameters must be globalized
+ params[i] = args[i+2];
+ }
+
+ // params is passed to action, and released in action's destructor
+ ScheduledAction* action = new ScheduledAction(
+ v8::Handle<v8::Function>::Cast(function), param_count, params);
+
+ delete[] params;
+
+ id = DOMTimer::install(script_context, action, timeout, single_shot);
+ } else {
+ // TODO(fqian): what's the right return value if failed.
+ return v8::Undefined();
+ }
+ return v8::Integer::New(id);
+}
+
+
+// DOMWindow -------------------------------------------------------------------
+
+static bool IsAscii(const String& str) {
+ for (size_t i = 0; i < str.length(); i++) {
+ if (str[i] > 0xFF)
+ return false;
+ }
+ return true;
+}
+
+static v8::Handle<v8::Value> Base64Convert(const String& str, bool encode) {
+ if (!IsAscii(str)) {
+ V8Proxy::SetDOMException(INVALID_CHARACTER_ERR);
+ return v8::Handle<v8::Value>();
+ }
+
+ Vector<char> in(str.length());
+ for (size_t i = 0; i < str.length(); i++) {
+ in[i] = static_cast<char>(str[i]);
+ }
+ Vector<char> out;
+
+ if (encode) {
+ base64Encode(in, out);
+ } else {
+ if (!base64Decode(in, out)) {
+ V8Proxy::ThrowError(V8Proxy::GENERAL_ERROR, "Cannot decode base64");
+ return v8::Undefined();
+ }
+ }
+
+ return v8String(String(out.data(), out.size()));
+}
+
+CALLBACK_FUNC_DECL(DOMWindowAtob) {
+ INC_STATS("DOM.DOMWindow.atob()");
+ DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(
+ V8ClassIndex::DOMWINDOW, args.Holder());
+
+ if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ return v8::Undefined();
+
+ if (args.Length() < 1) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ if (args[0]->IsNull()) return v8String("");
+
+ String str = ToWebCoreString(args[0]);
+ return Base64Convert(str, false);
+}
+
+CALLBACK_FUNC_DECL(DOMWindowBtoa) {
+ INC_STATS("DOM.DOMWindow.btoa()");
+ DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(
+ V8ClassIndex::DOMWINDOW, args.Holder());
+
+ if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ return v8::Undefined();
+
+ if (args.Length() < 1) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ if (args[0]->IsNull()) return v8String("");
+
+ String str = ToWebCoreString(args[0]);
+ return Base64Convert(str, true);
+}
+
+// TODO(fqian): returning string is cheating, and we should
+// fix this by calling toString function on the receiver.
+// However, V8 implements toString in JavaScript, which requires
+// switching context of receiver. I consider it is dangerous.
+CALLBACK_FUNC_DECL(DOMWindowToString)
+{
+ INC_STATS("DOM.DOMWindow.toString()");
+ return args.This()->ObjectProtoToString();
+}
+
+CALLBACK_FUNC_DECL(DOMWindowNOP)
+{
+ INC_STATS("DOM.DOMWindow.nop()");
+ return v8::Undefined();
+}
+
+
+CALLBACK_FUNC_DECL(HTMLFormElementSubmit) {
+ INC_STATS("DOM.HTMLFormElement.submit()");
+
+ HTMLFormElement* form =
+ V8Proxy::DOMWrapperToNative<HTMLFormElement>(args.Holder());
+
+ form->submit(0, false, false);
+ return v8::Undefined();
+}
+
+static String EventNameFromAttributeName(const String& name) {
+ ASSERT(name.startsWith("on"));
+ String event_type = name.substring(2);
+
+ if (event_type.startsWith("w")) {
+ switch(event_type[event_type.length() - 1]) {
+ case 't':
+ event_type = "webkitAnimationStart";
+ break;
+ case 'n':
+ event_type = "webkitAnimationIteration";
+ break;
+ case 'd':
+ ASSERT(event_type.length() > 7);
+ if (event_type[7] == 'a')
+ event_type = "webkitAnimationEnd";
+ else
+ event_type = "webkitTransitionEnd";
+ break;
+ }
+ }
+
+ return event_type;
+}
+
+
+ACCESSOR_SETTER(DOMWindowEventHandler) {
+ v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(
+ V8ClassIndex::DOMWINDOW, info.This());
+ if (holder.IsEmpty())
+ return;
+
+ DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(
+ V8ClassIndex::DOMWINDOW, holder);
+ if (!imp->frame())
+ return;
+
+ Document* doc = imp->frame()->document();
+ if (!doc)
+ return;
+
+ String key = ToWebCoreString(name);
+ String event_type = EventNameFromAttributeName(key);
+
+ if (value->IsNull()) {
+ // Clear the event listener
+ doc->removeWindowInlineEventListenerForType(event_type);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->frame());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateV8EventListener(value, true);
+ if (listener) {
+ doc->setWindowInlineEventListenerForType(event_type, listener);
+ }
+ }
+}
+
+
+ACCESSOR_GETTER(DOMWindowEventHandler) {
+ v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(
+ V8ClassIndex::DOMWINDOW, info.This());
+ if (holder.IsEmpty())
+ return v8::Undefined();
+
+ DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(
+ V8ClassIndex::DOMWINDOW, holder);
+ if (!imp->frame())
+ return v8::Undefined();
+
+ Document* doc = imp->frame()->document();
+ if (!doc)
+ return v8::Undefined();
+
+ String key = ToWebCoreString(name);
+ String event_type = EventNameFromAttributeName(key);
+
+ EventListener* listener = doc->windowInlineEventListenerForType(event_type);
+ return V8Proxy::EventListenerToV8Object(listener);
+}
+
+
+// --------------- Security Checks -------------------------
+NAMED_ACCESS_CHECK(DOMWindow) {
+ ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW);
+ v8::Handle<v8::Value> window =
+ V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host);
+ if (window.IsEmpty())
+ return false; // the frame is gone.
+
+ DOMWindow* target_win =
+ V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
+
+ ASSERT(target_win);
+
+ Frame* target = target_win->frame();
+ if (!target)
+ return false;
+
+ if (key->IsString()) {
+ String name = ToWebCoreString(key);
+
+ // Allow access of GET and HAS if index is a subframe.
+ if ((type == v8::ACCESS_GET || type == v8::ACCESS_HAS) &&
+ target->tree()->child(name)) {
+ return true;
+ }
+ }
+
+ return V8Proxy::CanAccessFrame(target, false);
+}
+
+
+INDEXED_ACCESS_CHECK(DOMWindow) {
+ ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW);
+ v8::Handle<v8::Value> window =
+ V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host);
+ if (window.IsEmpty())
+ return false;
+
+ DOMWindow* target_win =
+ V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
+
+ ASSERT(target_win);
+
+ Frame* target = target_win->frame();
+ if (!target)
+ return false;
+
+ // Allow access of GET and HAS if index is a subframe.
+ if ((type == v8::ACCESS_GET || type == v8::ACCESS_HAS) &&
+ target->tree()->child(index)) {
+ return true;
+ }
+
+ return V8Proxy::CanAccessFrame(target, false);
+}
+
+
+INDEXED_ACCESS_CHECK(History) {
+ ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY);
+ // Only allow same origin access
+ History* imp =
+ V8Proxy::ToNativeObject<History>(V8ClassIndex::HISTORY, host);
+ return V8Proxy::CanAccessFrame(imp->frame(), false);
+}
+
+
+NAMED_ACCESS_CHECK(History) {
+ ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY);
+ // Only allow same origin access
+ History* imp =
+ V8Proxy::ToNativeObject<History>(V8ClassIndex::HISTORY, host);
+ return V8Proxy::CanAccessFrame(imp->frame(), false);
+}
+
+
+
+#undef INDEXED_ACCESS_CHECK
+#undef NAMED_ACCESS_CHECK
+#undef NAMED_PROPERTY_GETTER
+#undef NAMED_PROPERTY_SETTER
+
+
+// static
+Frame* V8Custom::GetTargetFrame(v8::Local<v8::Object> host,
+ v8::Local<v8::Value> data) {
+ Frame* target = 0;
+ switch (V8ClassIndex::FromInt(data->Int32Value())) {
+ case V8ClassIndex::DOMWINDOW: {
+ v8::Handle<v8::Value> window =
+ V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host);
+ if (window.IsEmpty())
+ return target;
+
+ DOMWindow* target_win =
+ V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
+ target = target_win->frame();
+ break;
+ }
+ case V8ClassIndex::LOCATION: {
+ History* imp =
+ V8Proxy::ToNativeObject<History>(V8ClassIndex::HISTORY, host);
+ target = imp->frame();
+ break;
+ }
+ case V8ClassIndex::HISTORY: {
+ Location* imp =
+ V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, host);
+ target = imp->frame();
+ break;
+ }
+ default:
+ break;
+ }
+ return target;
+}
+
+#if ENABLE(SVG)
+V8ClassIndex::V8WrapperType V8Custom::DowncastSVGPathSeg(void* path_seg) {
+ WebCore::SVGPathSeg *real_path_seg =
+ reinterpret_cast<WebCore::SVGPathSeg*>(path_seg);
+
+ switch (real_path_seg->pathSegType()) {
+#define MAKE_CASE(svg_val, v8_val) \
+ case WebCore::SVGPathSeg::svg_val: \
+ return V8ClassIndex::v8_val;
+
+MAKE_CASE(PATHSEG_CLOSEPATH, SVGPATHSEGCLOSEPATH)
+MAKE_CASE(PATHSEG_MOVETO_ABS, SVGPATHSEGMOVETOABS)
+MAKE_CASE(PATHSEG_MOVETO_REL, SVGPATHSEGMOVETOREL)
+MAKE_CASE(PATHSEG_LINETO_ABS, SVGPATHSEGLINETOABS)
+MAKE_CASE(PATHSEG_LINETO_REL, SVGPATHSEGLINETOREL)
+MAKE_CASE(PATHSEG_CURVETO_CUBIC_ABS, SVGPATHSEGCURVETOCUBICABS)
+MAKE_CASE(PATHSEG_CURVETO_CUBIC_REL, SVGPATHSEGCURVETOCUBICREL)
+MAKE_CASE(PATHSEG_CURVETO_QUADRATIC_ABS, SVGPATHSEGCURVETOQUADRATICABS)
+MAKE_CASE(PATHSEG_CURVETO_QUADRATIC_REL, SVGPATHSEGCURVETOQUADRATICREL)
+MAKE_CASE(PATHSEG_ARC_ABS, SVGPATHSEGARCABS)
+MAKE_CASE(PATHSEG_ARC_REL, SVGPATHSEGARCREL)
+MAKE_CASE(PATHSEG_LINETO_HORIZONTAL_ABS, SVGPATHSEGLINETOHORIZONTALABS)
+MAKE_CASE(PATHSEG_LINETO_HORIZONTAL_REL, SVGPATHSEGLINETOHORIZONTALREL)
+MAKE_CASE(PATHSEG_LINETO_VERTICAL_ABS, SVGPATHSEGLINETOVERTICALABS)
+MAKE_CASE(PATHSEG_LINETO_VERTICAL_REL, SVGPATHSEGLINETOVERTICALREL)
+MAKE_CASE(PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, SVGPATHSEGCURVETOCUBICSMOOTHABS)
+MAKE_CASE(PATHSEG_CURVETO_CUBIC_SMOOTH_REL, SVGPATHSEGCURVETOCUBICSMOOTHREL)
+MAKE_CASE(PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, \
+ SVGPATHSEGCURVETOQUADRATICSMOOTHABS)
+MAKE_CASE(PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, \
+ SVGPATHSEGCURVETOQUADRATICSMOOTHREL)
+
+#undef MAKE_CASE
+
+ default:
+ return V8ClassIndex::INVALID_CLASS_INDEX;
+ }
+}
+
+#endif // ENABLE(SVG)
+
+} // namespace WebCore
diff --git a/V8Binding/v8/v8_custom.h b/V8Binding/v8/v8_custom.h
new file mode 100644
index 0000000..a891e2e
--- /dev/null
+++ b/V8Binding/v8/v8_custom.h
@@ -0,0 +1,545 @@
+// 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_CUSTOM_H__
+#define V8_CUSTOM_H__
+
+#include <v8.h>
+#include "v8_index.h"
+
+struct NPObject;
+
+#define CALLBACK_FUNC_DECL(NAME) \
+v8::Handle<v8::Value> V8Custom::v8##NAME##Callback(const v8::Arguments& args)
+
+#define ACCESSOR_GETTER(NAME) \
+v8::Handle<v8::Value> V8Custom::v8##NAME##AccessorGetter(\
+ v8::Local<v8::String> name, const v8::AccessorInfo& info)
+
+#define ACCESSOR_SETTER(NAME) \
+void V8Custom::v8##NAME##AccessorSetter(v8::Local<v8::String> name, \
+ v8::Local<v8::Value> value, \
+ const v8::AccessorInfo& info)
+
+#define INDEXED_PROPERTY_GETTER(NAME) \
+v8::Handle<v8::Value> V8Custom::v8##NAME##IndexedPropertyGetter(\
+ uint32_t index, const v8::AccessorInfo& info)
+
+#define INDEXED_PROPERTY_SETTER(NAME) \
+v8::Handle<v8::Value> V8Custom::v8##NAME##IndexedPropertySetter(\
+ uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+
+#define INDEXED_PROPERTY_DELETER(NAME) \
+v8::Handle<v8::Boolean> V8Custom::v8##NAME##IndexedPropertyDeleter(\
+ uint32_t index, const v8::AccessorInfo& info)
+
+#define NAMED_PROPERTY_GETTER(NAME) \
+ v8::Handle<v8::Value> V8Custom::v8##NAME##NamedPropertyGetter(\
+ v8::Local<v8::String> name, const v8::AccessorInfo& info)
+
+#define NAMED_PROPERTY_SETTER(NAME) \
+ v8::Handle<v8::Value> V8Custom::v8##NAME##NamedPropertySetter(\
+ v8::Local<v8::String> name, v8::Local<v8::Value> value, \
+ const v8::AccessorInfo& info)
+
+#define NAMED_PROPERTY_DELETER(NAME) \
+ v8::Handle<v8::Boolean> V8Custom::v8##NAME##NamedPropertyDeleter(\
+ v8::Local<v8::String> name, const v8::AccessorInfo& info)
+
+#define NAMED_ACCESS_CHECK(NAME) \
+ bool V8Custom::v8##NAME##NamedSecurityCheck(v8::Local<v8::Object> host, \
+ v8::Local<v8::Value> key, \
+ v8::AccessType type, \
+ v8::Local<v8::Value> data)
+
+#define INDEXED_ACCESS_CHECK(NAME) \
+ bool V8Custom::v8##NAME##IndexedSecurityCheck(v8::Local<v8::Object> host, \
+ uint32_t index, \
+ v8::AccessType type, \
+ v8::Local<v8::Value> data)
+
+namespace WebCore {
+
+class Frame;
+class V8Proxy;
+class String;
+class HTMLCollection;
+class DOMWindow;
+
+class V8Custom {
+ public:
+
+ // Constants.
+ static const int kDOMWrapperTypeIndex = 0;
+ static const int kDOMWrapperObjectIndex = 1;
+ static const int kDefaultWrapperInternalFieldCount = 2;
+
+ static const int kNPObjectInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 0;
+
+ static const int kDocumentImplementationIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kDocumentMinimumInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 1;
+
+ static const int kHTMLDocumentMarkerIndex =
+ kDocumentMinimumInternalFieldCount + 0;
+ static const int kHTMLDocumentShadowIndex =
+ kDocumentMinimumInternalFieldCount + 1;
+ static const int kHTMLDocumentInternalFieldCount =
+ kDocumentMinimumInternalFieldCount + 2;
+
+ static const int kXMLHttpRequestCacheIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kXMLHttpRequestInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 1;
+
+ static const int kMessageChannelPort1Index =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kMessageChannelPort2Index =
+ kDefaultWrapperInternalFieldCount + 1;
+ static const int kMessageChannelInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 2;
+
+ static const int kMessagePortRequestCacheIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kMessagePortEntangledPortIndex =
+ kDefaultWrapperInternalFieldCount + 1;
+ static const int kMessagePortInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 2;
+
+#if ENABLE(WORKERS)
+ static const int kWorkerRequestCacheIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kWorkerInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 1;
+
+ static const int kWorkerContextRequestCacheIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kWorkerContextInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 1;
+#endif
+
+ static const int kDOMWindowHistoryIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kDOMWindowNavigatorIndex =
+ kDefaultWrapperInternalFieldCount + 1;
+ static const int kDOMWindowLocationIndex =
+ kDefaultWrapperInternalFieldCount + 2;
+ static const int kDOMWindowInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 3;
+
+ static const int kStyleSheetOwnerNodeIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kStyleSheetInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 1;
+
+#define DECLARE_PROPERTY_ACCESSOR_GETTER(NAME) \
+static v8::Handle<v8::Value> v8##NAME##AccessorGetter(\
+ v8::Local<v8::String> name, const v8::AccessorInfo& info);
+
+#define DECLARE_PROPERTY_ACCESSOR_SETTER(NAME) \
+static void v8##NAME##AccessorSetter(v8::Local<v8::String> name, \
+ v8::Local<v8::Value> value, \
+ const v8::AccessorInfo& info);
+
+#define DECLARE_PROPERTY_ACCESSOR(NAME) \
+ DECLARE_PROPERTY_ACCESSOR_GETTER(NAME) \
+ DECLARE_PROPERTY_ACCESSOR_SETTER(NAME)
+
+
+#define DECLARE_NAMED_PROPERTY_GETTER(NAME) \
+static v8::Handle<v8::Value> v8##NAME##NamedPropertyGetter(\
+ v8::Local<v8::String> name, const v8::AccessorInfo& info);
+
+#define DECLARE_NAMED_PROPERTY_SETTER(NAME) \
+static v8::Handle<v8::Value> v8##NAME##NamedPropertySetter(\
+ v8::Local<v8::String> name, \
+ v8::Local<v8::Value> value, \
+ const v8::AccessorInfo& info);
+
+#define DECLARE_NAMED_PROPERTY_DELETER(NAME) \
+static v8::Handle<v8::Boolean> v8##NAME##NamedPropertyDeleter(\
+ v8::Local<v8::String> name, const v8::AccessorInfo& info);
+
+#define USE_NAMED_PROPERTY_GETTER(NAME) \
+ V8Custom::v8##NAME##NamedPropertyGetter
+
+#define USE_NAMED_PROPERTY_SETTER(NAME) \
+ V8Custom::v8##NAME##NamedPropertySetter
+
+#define USE_NAMED_PROPERTY_DELETER(NAME) \
+ V8Custom::v8##NAME##NamedPropertyDeleter
+
+#define DECLARE_INDEXED_PROPERTY_GETTER(NAME) \
+static v8::Handle<v8::Value> v8##NAME##IndexedPropertyGetter(\
+ uint32_t index, const v8::AccessorInfo& info);
+
+#define DECLARE_INDEXED_PROPERTY_SETTER(NAME) \
+static v8::Handle<v8::Value> v8##NAME##IndexedPropertySetter(\
+ uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
+
+#define DECLARE_INDEXED_PROPERTY_DELETER(NAME) \
+static v8::Handle<v8::Boolean> v8##NAME##IndexedPropertyDeleter(\
+ uint32_t index, const v8::AccessorInfo& info);
+
+#define USE_INDEXED_PROPERTY_GETTER(NAME) \
+ V8Custom::v8##NAME##IndexedPropertyGetter
+
+#define USE_INDEXED_PROPERTY_SETTER(NAME) \
+ V8Custom::v8##NAME##IndexedPropertySetter
+
+#define USE_INDEXED_PROPERTY_DELETER(NAME) \
+ V8Custom::v8##NAME##IndexedPropertyDeleter
+
+#define DECLARE_CALLBACK(NAME) \
+static v8::Handle<v8::Value> v8##NAME##Callback(const v8::Arguments& args);
+
+#define USE_CALLBACK(NAME) \
+ V8Custom::v8##NAME##Callback
+
+#define DECLARE_NAMED_ACCESS_CHECK(NAME) \
+static bool v8##NAME##NamedSecurityCheck(v8::Local<v8::Object> host, \
+ v8::Local<v8::Value> key, \
+ v8::AccessType type, \
+ v8::Local<v8::Value> data);
+
+#define DECLARE_INDEXED_ACCESS_CHECK(NAME) \
+static bool v8##NAME##IndexedSecurityCheck(v8::Local<v8::Object> host, \
+ uint32_t index, \
+ v8::AccessType type, \
+ v8::Local<v8::Value> data);
+
+DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DStrokeStyle)
+DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DFillStyle)
+// Customized getter&setter of DOMWindow.location
+DECLARE_PROPERTY_ACCESSOR_SETTER(DOMWindowLocation)
+// Customized setter of DOMWindow.opener
+DECLARE_PROPERTY_ACCESSOR_SETTER(DOMWindowOpener)
+
+DECLARE_PROPERTY_ACCESSOR(DocumentLocation)
+DECLARE_PROPERTY_ACCESSOR(DocumentImplementation)
+DECLARE_PROPERTY_ACCESSOR_GETTER(EventSrcElement)
+DECLARE_PROPERTY_ACCESSOR(EventReturnValue)
+DECLARE_PROPERTY_ACCESSOR_GETTER(EventDataTransfer)
+DECLARE_PROPERTY_ACCESSOR_GETTER(EventClipboardData)
+
+// Getter/Setter for window event handlers
+DECLARE_PROPERTY_ACCESSOR(DOMWindowEventHandler)
+// Getter/Setter for Element event handlers
+DECLARE_PROPERTY_ACCESSOR(ElementEventHandler)
+
+// HTMLCanvasElement
+DECLARE_CALLBACK(HTMLCanvasElementGetContext)
+
+// Customized setter of src and location on HTMLFrameElement
+DECLARE_PROPERTY_ACCESSOR_SETTER(HTMLFrameElementSrc)
+DECLARE_PROPERTY_ACCESSOR_SETTER(HTMLFrameElementLocation)
+// Customized setter of src on HTMLIFrameElement
+DECLARE_PROPERTY_ACCESSOR_SETTER(HTMLIFrameElementSrc)
+// Customized setter of Attr.value
+DECLARE_PROPERTY_ACCESSOR_SETTER(AttrValue)
+
+// Customized setter of HTMLOptionsCollection length
+DECLARE_PROPERTY_ACCESSOR(HTMLOptionsCollectionLength)
+
+DECLARE_CALLBACK(HTMLInputElementSetSelectionRange)
+
+// Customized accessors for HTMLInputElement
+DECLARE_PROPERTY_ACCESSOR(HTMLInputElementSelectionStart)
+DECLARE_PROPERTY_ACCESSOR(HTMLInputElementSelectionEnd)
+
+DECLARE_NAMED_ACCESS_CHECK(Location)
+DECLARE_INDEXED_ACCESS_CHECK(History)
+
+DECLARE_NAMED_ACCESS_CHECK(History)
+DECLARE_INDEXED_ACCESS_CHECK(Location)
+
+// HTMLCollection customized functions.
+DECLARE_CALLBACK(HTMLCollectionItem)
+DECLARE_CALLBACK(HTMLCollectionNamedItem)
+// HTMLCollections are callable as functions.
+DECLARE_CALLBACK(HTMLCollectionCallAsFunction)
+
+// HTMLSelectElement customized functions.
+DECLARE_CALLBACK(HTMLSelectElementRemove)
+
+// HTMLOptionsCollection customized functions.
+DECLARE_CALLBACK(HTMLOptionsCollectionRemove)
+DECLARE_CALLBACK(HTMLOptionsCollectionAdd)
+
+// HTMLDocument customized functions
+DECLARE_CALLBACK(HTMLDocumentWrite)
+DECLARE_CALLBACK(HTMLDocumentWriteln)
+DECLARE_CALLBACK(HTMLDocumentOpen)
+DECLARE_PROPERTY_ACCESSOR(HTMLDocumentAll)
+DECLARE_NAMED_PROPERTY_GETTER(HTMLDocument)
+DECLARE_NAMED_PROPERTY_DELETER(HTMLDocument)
+
+// Document customized functions
+DECLARE_CALLBACK(DocumentEvaluate)
+DECLARE_CALLBACK(DocumentGetCSSCanvasContext)
+
+// Window customized functions
+DECLARE_CALLBACK(DOMWindowAddEventListener)
+DECLARE_CALLBACK(DOMWindowRemoveEventListener)
+DECLARE_CALLBACK(DOMWindowPostMessage)
+DECLARE_CALLBACK(DOMWindowSetTimeout)
+DECLARE_CALLBACK(DOMWindowSetInterval)
+DECLARE_CALLBACK(DOMWindowAtob)
+DECLARE_CALLBACK(DOMWindowBtoa)
+DECLARE_CALLBACK(DOMWindowNOP)
+DECLARE_CALLBACK(DOMWindowToString)
+DECLARE_CALLBACK(DOMWindowShowModalDialog)
+DECLARE_CALLBACK(DOMWindowOpen)
+DECLARE_CALLBACK(DOMWindowClearTimeout)
+DECLARE_CALLBACK(DOMWindowClearInterval)
+
+DECLARE_CALLBACK(DOMParserConstructor)
+DECLARE_CALLBACK(MessageChannelConstructor)
+DECLARE_CALLBACK(WebKitCSSMatrixConstructor)
+DECLARE_CALLBACK(WebKitPointConstructor)
+DECLARE_CALLBACK(XMLHttpRequestConstructor)
+DECLARE_CALLBACK(XMLSerializerConstructor)
+DECLARE_CALLBACK(XPathEvaluatorConstructor)
+DECLARE_CALLBACK(XSLTProcessorConstructor)
+
+// Implementation of custom XSLTProcessor methods.
+DECLARE_CALLBACK(XSLTProcessorImportStylesheet)
+DECLARE_CALLBACK(XSLTProcessorTransformToFragment)
+DECLARE_CALLBACK(XSLTProcessorTransformToDocument)
+DECLARE_CALLBACK(XSLTProcessorSetParameter)
+DECLARE_CALLBACK(XSLTProcessorGetParameter)
+DECLARE_CALLBACK(XSLTProcessorRemoveParameter)
+
+// CSSPrimitiveValue customized functions
+DECLARE_CALLBACK(CSSPrimitiveValueGetRGBColorValue)
+
+// Canvas 2D customized functions
+DECLARE_CALLBACK(CanvasRenderingContext2DSetStrokeColor)
+DECLARE_CALLBACK(CanvasRenderingContext2DSetFillColor)
+DECLARE_CALLBACK(CanvasRenderingContext2DStrokeRect)
+DECLARE_CALLBACK(CanvasRenderingContext2DSetShadow)
+DECLARE_CALLBACK(CanvasRenderingContext2DDrawImage)
+DECLARE_CALLBACK(CanvasRenderingContext2DDrawImageFromRect)
+DECLARE_CALLBACK(CanvasRenderingContext2DCreatePattern)
+DECLARE_CALLBACK(CanvasRenderingContext2DFillText)
+DECLARE_CALLBACK(CanvasRenderingContext2DStrokeText)
+DECLARE_CALLBACK(CanvasRenderingContext2DPutImageData)
+
+// Implementation of Clipboard attributes and methods.
+DECLARE_PROPERTY_ACCESSOR_GETTER(ClipboardTypes)
+DECLARE_CALLBACK(ClipboardClearData)
+DECLARE_CALLBACK(ClipboardGetData)
+DECLARE_CALLBACK(ClipboardSetData)
+DECLARE_CALLBACK(ClipboardSetDragImage);
+
+// Implementation of Element methods.
+DECLARE_CALLBACK(ElementQuerySelector)
+DECLARE_CALLBACK(ElementQuerySelectorAll)
+DECLARE_CALLBACK(ElementSetAttribute)
+DECLARE_CALLBACK(ElementSetAttributeNode)
+DECLARE_CALLBACK(ElementSetAttributeNS)
+DECLARE_CALLBACK(ElementSetAttributeNodeNS)
+
+// Implementation of custom Location methods.
+DECLARE_PROPERTY_ACCESSOR_SETTER(LocationProtocol)
+DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHost)
+DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHostname)
+DECLARE_PROPERTY_ACCESSOR_SETTER(LocationPort)
+DECLARE_PROPERTY_ACCESSOR_SETTER(LocationPathname)
+DECLARE_PROPERTY_ACCESSOR_SETTER(LocationSearch)
+DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHash)
+DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHref)
+DECLARE_PROPERTY_ACCESSOR_GETTER(LocationAssign)
+DECLARE_PROPERTY_ACCESSOR_GETTER(LocationReplace)
+DECLARE_PROPERTY_ACCESSOR_GETTER(LocationReload)
+DECLARE_CALLBACK(LocationAssign)
+DECLARE_CALLBACK(LocationReplace)
+DECLARE_CALLBACK(LocationReload)
+DECLARE_CALLBACK(LocationToString)
+DECLARE_CALLBACK(LocationValueOf)
+
+// Implementation of EventTarget::addEventListener
+// and EventTarget::removeEventListener
+DECLARE_CALLBACK(NodeAddEventListener)
+DECLARE_CALLBACK(NodeRemoveEventListener)
+
+// Custom implementation is Navigator properties.
+// We actually only need this because WebKit has
+// navigator.appVersion as custom. Our version just
+// passes through.
+DECLARE_PROPERTY_ACCESSOR(NavigatorAppVersion)
+
+// Custom implementation of XMLHttpRequest properties
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnabort)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnerror)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnload)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnloadstart)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnprogress)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnreadystatechange)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestResponseText)
+DECLARE_CALLBACK(XMLHttpRequestAddEventListener)
+DECLARE_CALLBACK(XMLHttpRequestRemoveEventListener)
+DECLARE_CALLBACK(XMLHttpRequestOpen)
+DECLARE_CALLBACK(XMLHttpRequestSend)
+DECLARE_CALLBACK(XMLHttpRequestSetRequestHeader)
+DECLARE_CALLBACK(XMLHttpRequestGetResponseHeader)
+DECLARE_CALLBACK(XMLHttpRequestOverrideMimeType)
+DECLARE_CALLBACK(XMLHttpRequestDispatchEvent)
+
+// Custom implementation of XMLHttpRequestUpload properties
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnabort)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnerror)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnload)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnloadstart)
+DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnprogress)
+DECLARE_CALLBACK(XMLHttpRequestUploadAddEventListener)
+DECLARE_CALLBACK(XMLHttpRequestUploadRemoveEventListener)
+DECLARE_CALLBACK(XMLHttpRequestUploadDispatchEvent)
+
+// Custom implementation of TreeWalker functions
+DECLARE_CALLBACK(TreeWalkerParentNode)
+DECLARE_CALLBACK(TreeWalkerFirstChild)
+DECLARE_CALLBACK(TreeWalkerLastChild)
+DECLARE_CALLBACK(TreeWalkerNextNode)
+DECLARE_CALLBACK(TreeWalkerPreviousNode)
+DECLARE_CALLBACK(TreeWalkerNextSibling)
+DECLARE_CALLBACK(TreeWalkerPreviousSibling)
+
+// Custom implementation of InspectorController functions
+DECLARE_CALLBACK(InspectorControllerDebuggerEnabled)
+DECLARE_CALLBACK(InspectorControllerPauseOnExceptions)
+DECLARE_CALLBACK(InspectorControllerProfilerEnabled)
+#if ENABLE(DATABASE)
+DECLARE_CALLBACK(InspectorControllerDatabaseTableNames)
+#endif
+DECLARE_CALLBACK(InspectorControllerWrapCallback)
+
+// Custom implementation of NodeIterator functions
+DECLARE_CALLBACK(NodeIteratorNextNode)
+DECLARE_CALLBACK(NodeIteratorPreviousNode)
+
+// Custom implementation of NodeFilter function
+DECLARE_CALLBACK(NodeFilterAcceptNode)
+
+// Custom implementation of HTMLFormElement
+DECLARE_CALLBACK(HTMLFormElementSubmit)
+
+DECLARE_INDEXED_PROPERTY_GETTER(DOMStringList)
+DECLARE_CALLBACK(DOMStringListItem)
+
+DECLARE_NAMED_PROPERTY_GETTER(DOMWindow)
+DECLARE_INDEXED_PROPERTY_GETTER(DOMWindow)
+DECLARE_NAMED_ACCESS_CHECK(DOMWindow)
+DECLARE_INDEXED_ACCESS_CHECK(DOMWindow)
+
+DECLARE_NAMED_PROPERTY_GETTER(HTMLFrameSetElement)
+DECLARE_NAMED_PROPERTY_GETTER(HTMLFormElement)
+DECLARE_NAMED_PROPERTY_GETTER(NodeList)
+DECLARE_NAMED_PROPERTY_GETTER(NamedNodeMap)
+DECLARE_NAMED_PROPERTY_GETTER(CSSStyleDeclaration)
+DECLARE_NAMED_PROPERTY_SETTER(CSSStyleDeclaration)
+DECLARE_NAMED_PROPERTY_GETTER(HTMLPlugInElement)
+DECLARE_NAMED_PROPERTY_SETTER(HTMLPlugInElement)
+DECLARE_INDEXED_PROPERTY_GETTER(HTMLPlugInElement)
+DECLARE_INDEXED_PROPERTY_SETTER(HTMLPlugInElement)
+
+// Plugin object can be called as function.
+DECLARE_CALLBACK(HTMLPlugInElement)
+
+DECLARE_NAMED_PROPERTY_GETTER(StyleSheetList)
+DECLARE_INDEXED_PROPERTY_GETTER(NamedNodeMap)
+DECLARE_INDEXED_PROPERTY_GETTER(HTMLFormElement)
+DECLARE_INDEXED_PROPERTY_GETTER(HTMLOptionsCollection)
+DECLARE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection)
+DECLARE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection)
+DECLARE_NAMED_PROPERTY_GETTER(HTMLCollection)
+
+// Canvas and supporting classes
+DECLARE_INDEXED_PROPERTY_GETTER(CanvasPixelArray)
+DECLARE_INDEXED_PROPERTY_SETTER(CanvasPixelArray)
+
+// MessagePort
+DECLARE_PROPERTY_ACCESSOR(MessagePortOnmessage)
+DECLARE_PROPERTY_ACCESSOR(MessagePortOnclose)
+DECLARE_CALLBACK(MessagePortStartConversation)
+DECLARE_CALLBACK(MessagePortAddEventListener)
+DECLARE_CALLBACK(MessagePortRemoveEventListener)
+
+// Database
+DECLARE_CALLBACK(DatabaseChangeVersion)
+DECLARE_CALLBACK(DatabaseTransaction)
+DECLARE_CALLBACK(SQLTransactionExecuteSql)
+DECLARE_CALLBACK(SQLResultSetRowListItem)
+
+// SVG custom properties and callbacks
+#if ENABLE(SVG)
+DECLARE_PROPERTY_ACCESSOR_GETTER(SVGLengthValue)
+DECLARE_CALLBACK(SVGLengthConvertToSpecifiedUnits)
+DECLARE_CALLBACK(SVGMatrixInverse)
+DECLARE_CALLBACK(SVGMatrixRotateFromVector)
+DECLARE_CALLBACK(SVGElementInstanceAddEventListener)
+DECLARE_CALLBACK(SVGElementInstanceRemoveEventListener)
+#endif
+
+// Worker
+#if ENABLE(WORKERS)
+DECLARE_PROPERTY_ACCESSOR(WorkerOnmessage)
+DECLARE_PROPERTY_ACCESSOR(WorkerOnerror)
+DECLARE_CALLBACK(WorkerConstructor)
+DECLARE_CALLBACK(WorkerAddEventListener)
+DECLARE_CALLBACK(WorkerRemoveEventListener)
+
+DECLARE_PROPERTY_ACCESSOR_GETTER(WorkerContextSelf)
+DECLARE_PROPERTY_ACCESSOR(WorkerContextOnmessage)
+DECLARE_CALLBACK(WorkerContextImportScripts)
+DECLARE_CALLBACK(WorkerContextSetTimeout)
+DECLARE_CALLBACK(WorkerContextClearTimeout)
+DECLARE_CALLBACK(WorkerContextSetInterval)
+DECLARE_CALLBACK(WorkerContextClearInterval)
+DECLARE_CALLBACK(WorkerContextAddEventListener)
+DECLARE_CALLBACK(WorkerContextRemoveEventListener)
+#endif
+
+#undef DECLARE_INDEXED_ACCESS_CHECK
+#undef DECLARE_NAMED_ACCESS_CHECK
+
+#undef DECLARE_PROPERTY_ACCESSOR_SETTER
+#undef DECLARE_PROPERTY_ACCESSOR_GETTER
+#undef DECLARE_PROPERTY_ACCESSOR
+
+#undef DECLARE_NAMED_PROPERTY_GETTER
+#undef DECLARE_NAMED_PROPERTY_SETTER
+#undef DECLARE_NAMED_PROPERTY_DELETER
+
+#undef DECLARE_INDEXED_PROPERTY_GETTER
+#undef DECLARE_INDEXED_PROPERTY_SETTER
+#undef DECLARE_INDEXED_PROPERTY_DELETER
+
+#undef DECLARE_CALLBACK
+
+ // Returns the NPObject corresponding to an HTMLElement object.
+ static NPObject* GetHTMLPlugInElementNPObject(v8::Handle<v8::Object> object);
+
+ // Returns the owner frame pointer of a DOM wrapper object. It only works for
+ // these DOM objects requiring cross-domain access check.
+ static Frame* GetTargetFrame(v8::Local<v8::Object> host,
+ v8::Local<v8::Value> data);
+
+ // Special case for downcasting SVG path segments
+#if ENABLE(SVG)
+ static V8ClassIndex::V8WrapperType DowncastSVGPathSeg(void* path_seg);
+#endif
+
+ private:
+ static v8::Handle<v8::Value> WindowSetTimeoutImpl(const v8::Arguments& args,
+ bool single_shot);
+ static void ClearTimeoutImpl(const v8::Arguments& args);
+ static void WindowSetLocation(DOMWindow*, const String&);
+};
+
+} // namespace WebCore
+
+#endif // V8_CUSTOM_H__
diff --git a/V8Binding/v8/v8_helpers.cpp b/V8Binding/v8/v8_helpers.cpp
new file mode 100644
index 0000000..7a72ab5
--- /dev/null
+++ b/V8Binding/v8/v8_helpers.cpp
@@ -0,0 +1,59 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#define max max
+#define min min
+#include "v8_helpers.h"
+#include "v8_proxy.h"
+#include "v8_index.h"
+#include "NPV8Object.h"
+
+#include "DOMWindow.h"
+
+using WebCore::V8Custom;
+
+void WrapNPObject(v8::Handle<v8::Object> obj, NPObject* npobj)
+{
+ WebCore::V8Proxy::SetDOMWrapper(obj, WebCore::V8ClassIndex::NPOBJECT, npobj);
+}
+
+v8::Local<v8::Context> getV8Context(NPP npp, NPObject* npobj)
+{
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npobj);
+ return WebCore::V8Proxy::GetContext(object->rootObject->frame());
+}
+
+WebCore::V8Proxy* GetV8Proxy(NPObject* npobj)
+{
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npobj);
+ WebCore::Frame* frame = object->rootObject->frame();
+ return WebCore::V8Proxy::retrieve(frame);
+}
diff --git a/V8Binding/v8/v8_helpers.h b/V8Binding/v8/v8_helpers.h
new file mode 100644
index 0000000..b7f15aa
--- /dev/null
+++ b/V8Binding/v8/v8_helpers.h
@@ -0,0 +1,29 @@
+// 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_HELPERS_H__
+#define V8_HELPERS_H__
+
+#if PLATFORM(CHROMIUM)
+#include "third_party/npapi/bindings/npruntime.h"
+#else
+#include "bridge/npruntime.h" // use WebCore version
+#endif
+
+#include <v8.h>
+
+namespace WebCore {
+ class V8Proxy;
+}
+
+// Associates an NPObject with a V8 object.
+void WrapNPObject(v8::Handle<v8::Object> obj, NPObject *npobj);
+
+// Retrieves the V8 Context from the NP context pr obj (at most 1 may be NULL).
+v8::Local<v8::Context> getV8Context(NPP npp, NPObject* npobj);
+
+// Get V8Proxy object from an NPObject.
+WebCore::V8Proxy* GetV8Proxy(NPObject* npobj);
+
+#endif // V8_HELPERS_H__
diff --git a/V8Binding/v8/v8_index.cpp b/V8Binding/v8/v8_index.cpp
new file mode 100644
index 0000000..1078847
--- /dev/null
+++ b/V8Binding/v8/v8_index.cpp
@@ -0,0 +1,424 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#include "v8_index.h"
+
+// TODO: Can we use a macro to include necessary headers by using
+// WRAPPER_TYPES?
+#include "V8Attr.h"
+#include "V8BarInfo.h"
+#include "V8CanvasRenderingContext2D.h"
+#include "V8CanvasGradient.h"
+#include "V8CanvasPattern.h"
+#include "V8CanvasPixelArray.h"
+#include "V8CDATASection.h"
+#include "V8CharacterData.h"
+#include "V8ClientRect.h"
+#include "V8ClientRectList.h"
+#include "V8Clipboard.h"
+#include "V8Comment.h"
+#include "V8Console.h"
+#include "V8Counter.h"
+#include "V8CSSStyleDeclaration.h"
+#include "V8CSSRule.h"
+#include "V8CSSStyleRule.h"
+#include "V8CSSCharsetRule.h"
+#include "V8CSSImportRule.h"
+#include "V8CSSMediaRule.h"
+#include "V8CSSFontFaceRule.h"
+#include "V8CSSPageRule.h"
+#include "V8CSSRuleList.h"
+#include "V8CSSPrimitiveValue.h"
+#include "V8CSSValue.h"
+#include "V8CSSValueList.h"
+#include "V8CSSStyleSheet.h"
+#include "V8CSSVariablesDeclaration.h"
+#include "V8CSSVariablesRule.h"
+#include "V8Document.h"
+#include "V8DocumentFragment.h"
+#include "V8DocumentType.h"
+#include "V8Element.h"
+#include "V8Entity.h"
+#include "V8EntityReference.h"
+#include "V8File.h"
+#include "V8FileList.h"
+#include "V8History.h"
+#include "V8HTMLCanvasElement.h"
+#include "V8UndetectableHTMLCollection.h"
+#include "V8HTMLCollection.h"
+#include "V8HTMLDocument.h"
+#include "V8HTMLElement.h"
+#include "V8HTMLOptionsCollection.h"
+#include "V8HTMLAnchorElement.h"
+#include "V8HTMLAppletElement.h"
+#include "V8HTMLAreaElement.h"
+#include "V8HTMLBaseElement.h"
+#include "V8HTMLBaseFontElement.h"
+#include "V8HTMLBlockquoteElement.h"
+#include "V8HTMLBodyElement.h"
+#include "V8HTMLBRElement.h"
+#include "V8HTMLButtonElement.h"
+#include "V8HTMLCanvasElement.h"
+#include "V8HTMLModElement.h"
+#include "V8HTMLDirectoryElement.h"
+#include "V8HTMLDivElement.h"
+#include "V8HTMLDListElement.h"
+#include "V8HTMLEmbedElement.h"
+#include "V8HTMLFieldSetElement.h"
+#include "V8HTMLFormElement.h"
+#include "V8HTMLFontElement.h"
+#include "V8HTMLFrameElement.h"
+#include "V8HTMLFrameSetElement.h"
+#include "V8HTMLHeadingElement.h"
+#include "V8HTMLHeadElement.h"
+#include "V8HTMLHRElement.h"
+#include "V8HTMLHtmlElement.h"
+#include "V8HTMLIFrameElement.h"
+#include "V8HTMLImageElement.h"
+#include "V8HTMLInputElement.h"
+#include "V8HTMLIsIndexElement.h"
+#include "V8HTMLLabelElement.h"
+#include "V8HTMLLegendElement.h"
+#include "V8HTMLLIElement.h"
+#include "V8HTMLLinkElement.h"
+#include "V8HTMLMapElement.h"
+#include "V8HTMLMarqueeElement.h"
+#include "V8HTMLMenuElement.h"
+#include "V8HTMLMetaElement.h"
+#include "V8HTMLObjectElement.h"
+#include "V8HTMLOListElement.h"
+#include "V8HTMLOptGroupElement.h"
+#include "V8HTMLOptionElement.h"
+#include "V8HTMLParagraphElement.h"
+#include "V8HTMLParamElement.h"
+#include "V8HTMLPreElement.h"
+#include "V8HTMLQuoteElement.h"
+#include "V8HTMLScriptElement.h"
+#include "V8HTMLSelectElement.h"
+#include "V8HTMLStyleElement.h"
+#include "V8HTMLTableCaptionElement.h"
+#include "V8HTMLTableColElement.h"
+#include "V8HTMLTableElement.h"
+#include "V8HTMLTableSectionElement.h"
+#include "V8HTMLTableCellElement.h"
+#include "V8HTMLTableRowElement.h"
+#include "V8HTMLTextAreaElement.h"
+#include "V8HTMLTitleElement.h"
+#include "V8HTMLUListElement.h"
+#include "V8ImageData.h"
+#include "V8MediaList.h"
+#include "V8MessageChannel.h"
+#include "V8MessageEvent.h"
+#include "V8MessagePort.h"
+#include "V8NamedNodeMap.h"
+#include "V8Node.h"
+#include "V8NodeList.h"
+#include "V8NodeFilter.h"
+#include "V8Notation.h"
+#include "V8ProcessingInstruction.h"
+#include "V8ProgressEvent.h"
+#include "V8StyleSheet.h"
+#include "V8Text.h"
+#include "V8TextEvent.h"
+#include "V8DOMCoreException.h"
+#include "V8DOMParser.h"
+#include "V8DOMStringList.h"
+#include "V8DOMWindow.h"
+#include "V8Event.h"
+#include "V8EventException.h"
+#include "V8KeyboardEvent.h"
+#include "V8MouseEvent.h"
+#include "V8WebKitAnimationEvent.h"
+#include "V8WebKitCSSKeyframeRule.h"
+#include "V8WebKitCSSKeyframesRule.h"
+#include "V8WebKitCSSMatrix.h"
+#include "V8WebKitCSSTransformValue.h"
+#include "V8WebKitPoint.h"
+#include "V8WebKitTransitionEvent.h"
+#include "V8WheelEvent.h"
+#include "V8UIEvent.h"
+#include "V8MutationEvent.h"
+#include "V8OverflowEvent.h"
+#include "V8Location.h"
+#include "V8Screen.h"
+#include "V8DOMSelection.h"
+#include "V8Navigator.h"
+#include "V8MimeType.h"
+#include "V8MimeTypeArray.h"
+#include "V8Plugin.h"
+#include "V8PluginArray.h"
+#include "V8Range.h"
+#include "V8RangeException.h"
+#include "V8Rect.h"
+#include "V8NodeIterator.h"
+#include "V8TextMetrics.h"
+#include "V8TreeWalker.h"
+#include "V8StyleSheetList.h"
+#include "V8DOMImplementation.h"
+
+#if ENABLE(XPATH)
+#include "V8XPathResult.h"
+#include "V8XPathException.h"
+#include "V8XPathExpression.h"
+#include "V8XPathNSResolver.h"
+#include "V8XPathEvaluator.h"
+#endif
+#if ENABLE(XSLT)
+#include "V8XSLTProcessor.h"
+#endif
+
+#include "V8XMLHttpRequest.h"
+#include "V8XMLHttpRequestException.h"
+#include "V8XMLHttpRequestProgressEvent.h"
+#include "V8XMLHttpRequestUpload.h"
+#include "V8XMLSerializer.h"
+#include "V8RGBColor.h"
+
+#if PLATFORM(CHROMIUM)
+#include "V8InspectorController.h"
+#include "V8Database.h"
+#include "V8SQLError.h"
+#include "V8SQLResultSet.h"
+#include "V8SQLResultSetRowList.h"
+#include "V8SQLTransaction.h"
+#endif
+
+#if ENABLE(SVG_ANIMATION)
+#include "V8SVGAnimateColorElement.h"
+#include "V8SVGAnimateElement.h"
+#include "V8SVGAnimateTransformElement.h"
+#include "V8SVGAnimationElement.h"
+#include "V8SVGSetElement.h"
+#endif
+
+#if ENABLE(SVG_FILTERS)
+#include "V8SVGComponentTransferFunctionElement.h"
+#include "V8SVGFEBlendElement.h"
+#include "V8SVGFEColorMatrixElement.h"
+#include "V8SVGFEComponentTransferElement.h"
+#include "V8SVGFECompositeElement.h"
+#include "V8SVGFEDiffuseLightingElement.h"
+#include "V8SVGFEDisplacementMapElement.h"
+#include "V8SVGFEDistantLightElement.h"
+#include "V8SVGFEFloodElement.h"
+#include "V8SVGFEFuncAElement.h"
+#include "V8SVGFEFuncBElement.h"
+#include "V8SVGFEFuncGElement.h"
+#include "V8SVGFEFuncRElement.h"
+#include "V8SVGFEGaussianBlurElement.h"
+#include "V8SVGFEImageElement.h"
+#include "V8SVGFEMergeElement.h"
+#include "V8SVGFEMergeNodeElement.h"
+#include "V8SVGFEOffsetElement.h"
+#include "V8SVGFEPointLightElement.h"
+#include "V8SVGFESpecularLightingElement.h"
+#include "V8SVGFESpotLightElement.h"
+#include "V8SVGFETileElement.h"
+#include "V8SVGFETurbulenceElement.h"
+#include "V8SVGFilterElement.h"
+#endif
+
+#if ENABLE(SVG_FONTS)
+#include "V8SVGDefinitionSrcElement.h"
+#include "V8SVGFontFaceElement.h"
+#include "V8SVGFontFaceFormatElement.h"
+#include "V8SVGFontFaceNameElement.h"
+#include "V8SVGFontFaceSrcElement.h"
+#include "V8SVGFontFaceUriElement.h"
+#endif
+
+#if ENABLE(SVG_FOREIGN_OBJECT)
+#include "V8SVGForeignObjectElement.h"
+#endif
+
+#if ENABLE(SVG_USE)
+#include "V8SVGUseElement.h"
+#endif
+
+#if ENABLE(SVG)
+#include "V8SVGAElement.h"
+#include "V8SVGAltGlyphElement.h"
+#include "V8SVGCircleElement.h"
+#include "V8SVGClipPathElement.h"
+#include "V8SVGCursorElement.h"
+#include "V8SVGDefsElement.h"
+#include "V8SVGDescElement.h"
+#include "V8SVGElement.h"
+#include "V8SVGEllipseElement.h"
+#include "V8SVGException.h"
+#include "V8SVGGElement.h"
+#include "V8SVGGlyphElement.h"
+#include "V8SVGGradientElement.h"
+#include "V8SVGImageElement.h"
+#include "V8SVGLinearGradientElement.h"
+#include "V8SVGLineElement.h"
+#include "V8SVGMarkerElement.h"
+#include "V8SVGMaskElement.h"
+#include "V8SVGMetadataElement.h"
+#include "V8SVGPathElement.h"
+#include "V8SVGPatternElement.h"
+#include "V8SVGPolygonElement.h"
+#include "V8SVGPolylineElement.h"
+#include "V8SVGRadialGradientElement.h"
+#include "V8SVGRectElement.h"
+#include "V8SVGScriptElement.h"
+#include "V8SVGStopElement.h"
+#include "V8SVGStyleElement.h"
+#include "V8SVGSVGElement.h"
+#include "V8SVGSwitchElement.h"
+#include "V8SVGSymbolElement.h"
+#include "V8SVGTextContentElement.h"
+#include "V8SVGTextElement.h"
+#include "V8SVGTextPathElement.h"
+#include "V8SVGTextPositioningElement.h"
+#include "V8SVGTitleElement.h"
+#include "V8SVGTRefElement.h"
+#include "V8SVGTSpanElement.h"
+#include "V8SVGViewElement.h"
+#include "V8SVGAngle.h"
+#include "V8SVGAnimatedAngle.h"
+#include "V8SVGAnimatedBoolean.h"
+#include "V8SVGAnimatedEnumeration.h"
+#include "V8SVGAnimatedInteger.h"
+#include "V8SVGAnimatedLength.h"
+#include "V8SVGAnimatedLengthList.h"
+#include "V8SVGAnimatedNumber.h"
+#include "V8SVGAnimatedNumberList.h"
+#include "V8SVGAnimatedPoints.h"
+#include "V8SVGAnimatedPreserveAspectRatio.h"
+#include "V8SVGAnimatedRect.h"
+#include "V8SVGAnimatedString.h"
+#include "V8SVGAnimatedTransformList.h"
+#include "V8SVGColor.h"
+#include "V8SVGDocument.h"
+#include "V8SVGElementInstance.h"
+#include "V8SVGElementInstanceList.h"
+#include "V8SVGLength.h"
+#include "V8SVGLengthList.h"
+#include "V8SVGMatrix.h"
+#include "V8SVGNumber.h"
+#include "V8SVGNumberList.h"
+#include "V8SVGPaint.h"
+#include "V8SVGPathSeg.h"
+#include "V8SVGPathSegArcAbs.h"
+#include "V8SVGPathSegArcRel.h"
+#include "V8SVGPathSegClosePath.h"
+#include "V8SVGPathSegCurvetoCubicAbs.h"
+#include "V8SVGPathSegCurvetoCubicRel.h"
+#include "V8SVGPathSegCurvetoCubicSmoothAbs.h"
+#include "V8SVGPathSegCurvetoCubicSmoothRel.h"
+#include "V8SVGPathSegCurvetoQuadraticAbs.h"
+#include "V8SVGPathSegCurvetoQuadraticRel.h"
+#include "V8SVGPathSegCurvetoQuadraticSmoothAbs.h"
+#include "V8SVGPathSegCurvetoQuadraticSmoothRel.h"
+#include "V8SVGPathSegLinetoAbs.h"
+#include "V8SVGPathSegLinetoHorizontalAbs.h"
+#include "V8SVGPathSegLinetoHorizontalRel.h"
+#include "V8SVGPathSegLinetoRel.h"
+#include "V8SVGPathSegLinetoVerticalAbs.h"
+#include "V8SVGPathSegLinetoVerticalRel.h"
+#include "V8SVGPathSegList.h"
+#include "V8SVGPathSegMovetoAbs.h"
+#include "V8SVGPathSegMovetoRel.h"
+#include "V8SVGPoint.h"
+#include "V8SVGPointList.h"
+#include "V8SVGPreserveAspectRatio.h"
+#include "V8SVGRect.h"
+#include "V8SVGRenderingIntent.h"
+#include "V8SVGStringList.h"
+#include "V8SVGTransform.h"
+#include "V8SVGTransformList.h"
+#include "V8SVGUnitTypes.h"
+#include "V8SVGURIReference.h"
+#include "V8SVGZoomEvent.h"
+#endif
+
+#if ENABLE(VIDEO)
+#include "V8HTMLAudioElement.h"
+#include "V8HTMLMediaElement.h"
+#include "V8HTMLSourceElement.h"
+#include "V8HTMLVideoElement.h"
+#include "V8MediaError.h"
+#include "V8TimeRanges.h"
+#endif
+
+#if ENABLE(WORKERS)
+#include "V8Worker.h"
+#include "V8WorkerContext.h"
+#include "V8WorkerLocation.h"
+#include "V8WorkerNavigator.h"
+#endif
+
+#if PLATFORM(ANDROID)
+#include "V8Coordinates.h"
+#include "V8Geolocation.h"
+#include "V8Geoposition.h"
+#include "V8PositionError.h"
+#include "V8PositionErrorCallback.h"
+#include "V8Touch.h"
+#include "V8TouchList.h"
+#include "V8TouchEvent.h"
+#include "V8VoidCallback.h"
+#endif
+
+namespace WebCore {
+
+FunctionTemplateFactory V8ClassIndex::GetFactory(V8WrapperType type) {
+ switch (type) {
+#define MAKE_CASE(type, name)\
+ case V8ClassIndex::type: return V8##name::GetTemplate;
+ WRAPPER_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default: return NULL;
+ }
+}
+
+
+#define MAKE_CACHE(type, name)\
+ static v8::Persistent<v8::FunctionTemplate> name##_cache_;
+ ALL_WRAPPER_TYPES(MAKE_CACHE)
+#undef MAKE_CACHE
+
+
+v8::Persistent<v8::FunctionTemplate>* V8ClassIndex::GetCache(
+ V8WrapperType type) {
+ switch (type) {
+#define MAKE_CASE(type, name)\
+ case V8ClassIndex::type: return &name##_cache_;
+ ALL_WRAPPER_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default:
+ ASSERT(false);
+ return NULL;
+ }
+}
+
+} // namespace WebCore
diff --git a/V8Binding/v8/v8_index.h b/V8Binding/v8/v8_index.h
new file mode 100644
index 0000000..ae32ba2
--- /dev/null
+++ b/V8Binding/v8/v8_index.h
@@ -0,0 +1,510 @@
+// 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_INDEX_H__
+#define V8_INDEX_H__
+
+#include <v8.h>
+#include "PlatformString.h" // for WebCore::String
+
+namespace WebCore {
+
+typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
+
+#if ENABLE(VIDEO)
+#define VIDEO_HTMLELEMENT_TYPES(V) \
+ V(HTMLAUDIOELEMENT, HTMLAudioElement) \
+ V(HTMLMEDIAELEMENT, HTMLMediaElement) \
+ V(HTMLSOURCEELEMENT, HTMLSourceElement) \
+ V(HTMLVIDEOELEMENT, HTMLVideoElement)
+#define VIDEO_NONNODE_TYPES(V) \
+ V(MEDIAERROR, MediaError) \
+ V(TIMERANGES, TimeRanges)
+#else
+#define VIDEO_HTMLELEMENT_TYPES(V)
+#define VIDEO_NONNODE_TYPES(V)
+#endif
+
+#if ENABLE(WORKERS)
+#define WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V) \
+ V(WORKER, Worker)
+
+#define WORKER_NONNODE_WRAPPER_TYPES(V) \
+ V(WORKERCONTEXT, WorkerContext) \
+ V(WORKERLOCATION, WorkerLocation) \
+ V(WORKERNAVIGATOR, WorkerNavigator)
+#else
+#define WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V)
+#define WORKER_NONNODE_WRAPPER_TYPES(V)
+#endif
+
+#define DOM_NODE_TYPES(V) \
+ V(ATTR, Attr) \
+ V(CHARACTERDATA, CharacterData) \
+ V(CDATASECTION, CDATASection) \
+ V(COMMENT, Comment) \
+ V(DOCUMENT, Document) \
+ V(DOCUMENTFRAGMENT, DocumentFragment) \
+ V(DOCUMENTTYPE, DocumentType) \
+ V(ELEMENT, Element) \
+ V(ENTITY, Entity) \
+ V(ENTITYREFERENCE, EntityReference) \
+ V(HTMLDOCUMENT, HTMLDocument) \
+ V(NODE, Node) \
+ V(NOTATION, Notation) \
+ V(PROCESSINGINSTRUCTION, ProcessingInstruction) \
+ V(TEXT, Text) \
+ \
+ V(HTMLANCHORELEMENT, HTMLAnchorElement) \
+ V(HTMLAPPLETELEMENT, HTMLAppletElement) \
+ V(HTMLAREAELEMENT, HTMLAreaElement) \
+ V(HTMLBASEELEMENT, HTMLBaseElement) \
+ V(HTMLBASEFONTELEMENT, HTMLBaseFontElement) \
+ V(HTMLBLOCKQUOTEELEMENT, HTMLBlockquoteElement) \
+ V(HTMLBODYELEMENT, HTMLBodyElement) \
+ V(HTMLBRELEMENT, HTMLBRElement) \
+ V(HTMLBUTTONELEMENT, HTMLButtonElement) \
+ V(HTMLCANVASELEMENT, HTMLCanvasElement) \
+ V(HTMLDIRECTORYELEMENT, HTMLDirectoryElement) \
+ V(HTMLDIVELEMENT, HTMLDivElement) \
+ V(HTMLDLISTELEMENT, HTMLDListElement) \
+ V(HTMLEMBEDELEMENT, HTMLEmbedElement) \
+ V(HTMLFIELDSETELEMENT, HTMLFieldSetElement) \
+ V(HTMLFONTELEMENT, HTMLFontElement) \
+ V(HTMLFORMELEMENT, HTMLFormElement) \
+ V(HTMLFRAMEELEMENT, HTMLFrameElement) \
+ V(HTMLFRAMESETELEMENT, HTMLFrameSetElement) \
+ V(HTMLHEADINGELEMENT, HTMLHeadingElement) \
+ V(HTMLHEADELEMENT, HTMLHeadElement) \
+ V(HTMLHRELEMENT, HTMLHRElement) \
+ V(HTMLHTMLELEMENT, HTMLHtmlElement) \
+ V(HTMLIFRAMEELEMENT, HTMLIFrameElement) \
+ V(HTMLIMAGEELEMENT, HTMLImageElement) \
+ V(HTMLINPUTELEMENT, HTMLInputElement) \
+ V(HTMLISINDEXELEMENT, HTMLIsIndexElement) \
+ V(HTMLLABELELEMENT, HTMLLabelElement) \
+ V(HTMLLEGENDELEMENT, HTMLLegendElement) \
+ V(HTMLLIELEMENT, HTMLLIElement) \
+ V(HTMLLINKELEMENT, HTMLLinkElement) \
+ V(HTMLMAPELEMENT, HTMLMapElement) \
+ V(HTMLMARQUEEELEMENT, HTMLMarqueeElement) \
+ V(HTMLMENUELEMENT, HTMLMenuElement) \
+ V(HTMLMETAELEMENT, HTMLMetaElement) \
+ V(HTMLMODELEMENT, HTMLModElement) \
+ V(HTMLOBJECTELEMENT, HTMLObjectElement) \
+ V(HTMLOLISTELEMENT, HTMLOListElement) \
+ V(HTMLOPTGROUPELEMENT, HTMLOptGroupElement) \
+ V(HTMLOPTIONELEMENT, HTMLOptionElement) \
+ V(HTMLPARAGRAPHELEMENT, HTMLParagraphElement) \
+ V(HTMLPARAMELEMENT, HTMLParamElement) \
+ V(HTMLPREELEMENT, HTMLPreElement) \
+ V(HTMLQUOTEELEMENT, HTMLQuoteElement) \
+ V(HTMLSCRIPTELEMENT, HTMLScriptElement) \
+ V(HTMLSELECTELEMENT, HTMLSelectElement) \
+ V(HTMLSTYLEELEMENT, HTMLStyleElement) \
+ V(HTMLTABLECAPTIONELEMENT, HTMLTableCaptionElement) \
+ V(HTMLTABLECOLELEMENT, HTMLTableColElement) \
+ V(HTMLTABLEELEMENT, HTMLTableElement) \
+ V(HTMLTABLESECTIONELEMENT, HTMLTableSectionElement) \
+ V(HTMLTABLECELLELEMENT, HTMLTableCellElement) \
+ V(HTMLTABLEROWELEMENT, HTMLTableRowElement) \
+ V(HTMLTEXTAREAELEMENT, HTMLTextAreaElement) \
+ V(HTMLTITLEELEMENT, HTMLTitleElement) \
+ V(HTMLULISTELEMENT, HTMLUListElement) \
+ V(HTMLELEMENT, HTMLElement) \
+ VIDEO_HTMLELEMENT_TYPES(V)
+
+#if ENABLE(SVG_ANIMATION)
+#define SVG_ANIMATION_ELEMENT_TYPES(V) \
+ V(SVGANIMATECOLORELEMENT, SVGAnimateColorElement) \
+ V(SVGANIMATEELEMENT, SVGAnimateElement) \
+ V(SVGANIMATETRANSFORMELEMENT, SVGAnimateTransformElement) \
+ V(SVGANIMATIONELEMENT, SVGAnimationElement) \
+ V(SVGSETELEMENT, SVGSetElement)
+#else
+#define SVG_ANIMATION_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG_FILTERS)
+#define SVG_FILTERS_ELEMENT_TYPES(V) \
+ V(SVGCOMPONENTTRANSFERFUNCTIONELEMENT, SVGComponentTransferFunctionElement)\
+ V(SVGFEBLENDELEMENT, SVGFEBlendElement) \
+ V(SVGFECOLORMATRIXELEMENT, SVGFEColorMatrixElement) \
+ V(SVGFECOMPONENTTRANSFERELEMENT, SVGFEComponentTransferElement) \
+ V(SVGFECOMPOSITEELEMENT, SVGFECompositeElement) \
+ V(SVGFEDIFFUSELIGHTINGELEMENT, SVGFEDiffuseLightingElement) \
+ V(SVGFEDISPLACEMENTMAPELEMENT, SVGFEDisplacementMapElement) \
+ V(SVGFEDISTANTLIGHTELEMENT, SVGFEDistantLightElement) \
+ V(SVGFEFLOODELEMENT, SVGFEFloodElement) \
+ V(SVGFEFUNCAELEMENT, SVGFEFuncAElement) \
+ V(SVGFEFUNCBELEMENT, SVGFEFuncBElement) \
+ V(SVGFEFUNCGELEMENT, SVGFEFuncGElement) \
+ V(SVGFEFUNCRELEMENT, SVGFEFuncRElement) \
+ V(SVGFEGAUSSIANBLURELEMENT, SVGFEGaussianBlurElement) \
+ V(SVGFEIMAGEELEMENT, SVGFEImageElement) \
+ V(SVGFEMERGEELEMENT, SVGFEMergeElement) \
+ V(SVGFEMERGENODEELEMENT, SVGFEMergeNodeElement) \
+ V(SVGFEOFFSETELEMENT, SVGFEOffsetElement) \
+ V(SVGFEPOINTLIGHTELEMENT, SVGFEPointLightElement) \
+ V(SVGFESPECULARLIGHTINGELEMENT, SVGFESpecularLightingElement) \
+ V(SVGFESPOTLIGHTELEMENT, SVGFESpotLightElement) \
+ V(SVGFETILEELEMENT, SVGFETileElement) \
+ V(SVGFETURBULENCEELEMENT, SVGFETurbulenceElement) \
+ V(SVGFILTERELEMENT, SVGFilterElement)
+#else
+#define SVG_FILTERS_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG_FONTS)
+#define SVG_FONTS_ELEMENT_TYPES(V) \
+ V(SVGDEFINITIONSRCELEMENT, SVGDefinitionSrcElement) \
+ V(SVGFONTFACEELEMENT, SVGFontFaceElement) \
+ V(SVGFONTFACEFORMATELEMENT, SVGFontFaceFormatElement) \
+ V(SVGFONTFACENAMEELEMENT, SVGFontFaceNameElement) \
+ V(SVGFONTFACESRCELEMENT, SVGFontFaceSrcElement) \
+ V(SVGFONTFACEURIELEMENT, SVGFontFaceUriElement)
+#else
+#define SVG_FONTS_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG_FOREIGN_OBJECT)
+#define SVG_FOREIGN_OBJECT_ELEMENT_TYPES(V) \
+ V(SVGFOREIGNOBJECTELEMENT, SVGForeignObjectElement)
+#else
+#define SVG_FOREIGN_OBJECT_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG_USE)
+#define SVG_USE_ELEMENT_TYPES(V) \
+ V(SVGUSEELEMENT, SVGUseElement)
+#else
+#define SVG_USE_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG)
+#define SVG_NODE_TYPES(V) \
+ SVG_ANIMATION_ELEMENT_TYPES(V) \
+ SVG_FILTERS_ELEMENT_TYPES(V) \
+ SVG_FONTS_ELEMENT_TYPES(V) \
+ SVG_FOREIGN_OBJECT_ELEMENT_TYPES(V) \
+ SVG_USE_ELEMENT_TYPES(V) \
+ V(SVGAELEMENT, SVGAElement) \
+ V(SVGALTGLYPHELEMENT, SVGAltGlyphElement) \
+ V(SVGCIRCLEELEMENT, SVGCircleElement) \
+ V(SVGCLIPPATHELEMENT, SVGClipPathElement) \
+ V(SVGCURSORELEMENT, SVGCursorElement) \
+ V(SVGDEFSELEMENT, SVGDefsElement) \
+ V(SVGDESCELEMENT, SVGDescElement) \
+ V(SVGELLIPSEELEMENT, SVGEllipseElement) \
+ V(SVGGELEMENT, SVGGElement) \
+ V(SVGGLYPHELEMENT, SVGGlyphElement) \
+ V(SVGGRADIENTELEMENT, SVGGradientElement) \
+ V(SVGIMAGEELEMENT, SVGImageElement) \
+ V(SVGLINEARGRADIENTELEMENT, SVGLinearGradientElement) \
+ V(SVGLINEELEMENT, SVGLineElement) \
+ V(SVGMARKERELEMENT, SVGMarkerElement) \
+ V(SVGMASKELEMENT, SVGMaskElement) \
+ V(SVGMETADATAELEMENT, SVGMetadataElement) \
+ V(SVGPATHELEMENT, SVGPathElement) \
+ V(SVGPATTERNELEMENT, SVGPatternElement) \
+ V(SVGPOLYGONELEMENT, SVGPolygonElement) \
+ V(SVGPOLYLINEELEMENT, SVGPolylineElement) \
+ V(SVGRADIALGRADIENTELEMENT, SVGRadialGradientElement) \
+ V(SVGRECTELEMENT, SVGRectElement) \
+ V(SVGSCRIPTELEMENT, SVGScriptElement) \
+ V(SVGSTOPELEMENT, SVGStopElement) \
+ V(SVGSTYLEELEMENT, SVGStyleElement) \
+ V(SVGSVGELEMENT, SVGSVGElement) \
+ V(SVGSWITCHELEMENT, SVGSwitchElement) \
+ V(SVGSYMBOLELEMENT, SVGSymbolElement) \
+ V(SVGTEXTCONTENTELEMENT, SVGTextContentElement) \
+ V(SVGTEXTELEMENT, SVGTextElement) \
+ V(SVGTEXTPATHELEMENT, SVGTextPathElement) \
+ V(SVGTEXTPOSITIONINGELEMENT, SVGTextPositioningElement) \
+ V(SVGTITLEELEMENT, SVGTitleElement) \
+ V(SVGTREFELEMENT, SVGTRefElement) \
+ V(SVGTSPANELEMENT, SVGTSpanElement) \
+ V(SVGVIEWELEMENT, SVGViewElement) \
+ V(SVGELEMENT, SVGElement) \
+ \
+ V(SVGDOCUMENT, SVGDocument)
+#endif // SVG
+
+
+// ACTIVE_DOM_OBJECT_TYPES are DOM_OBJECT_TYPES that need special treatement
+// during GC.
+#define ACTIVE_DOM_OBJECT_TYPES(V) \
+ V(MESSAGEPORT, MessagePort) \
+ V(XMLHTTPREQUEST, XMLHttpRequest) \
+ WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V)
+
+// NOTE: DOM_OBJECT_TYPES is split into two halves because
+// Visual Studio's Intellinonsense crashes when macros get
+// too large. 10-29-08
+// DOM_OBJECT_TYPES are non-node DOM types.
+#define DOM_OBJECT_TYPES_1(V) \
+ V(BARINFO, BarInfo) \
+ V(CANVASGRADIENT, CanvasGradient) \
+ V(CANVASPATTERN, CanvasPattern) \
+ V(CANVASRENDERINGCONTEXT2D, CanvasRenderingContext2D) \
+ V(CLIENTRECT, ClientRect) \
+ V(CLIENTRECTLIST, ClientRectList) \
+ V(CLIPBOARD, Clipboard) \
+ V(CONSOLE, Console) \
+ V(COUNTER, Counter) \
+ V(CSSCHARSETRULE, CSSCharsetRule) \
+ V(CSSFONTFACERULE, CSSFontFaceRule) \
+ V(CSSIMPORTRULE, CSSImportRule) \
+ V(CSSMEDIARULE, CSSMediaRule) \
+ V(CSSPAGERULE, CSSPageRule) \
+ V(CSSPRIMITIVEVALUE, CSSPrimitiveValue) \
+ V(CSSRULE, CSSRule) \
+ V(CSSRULELIST, CSSRuleList) \
+ V(CSSSTYLEDECLARATION, CSSStyleDeclaration) \
+ V(CSSSTYLERULE, CSSStyleRule) \
+ V(CSSSTYLESHEET, CSSStyleSheet) \
+ V(CSSVALUE, CSSValue) \
+ V(CSSVALUELIST, CSSValueList) \
+ V(CSSVARIABLESDECLARATION, CSSVariablesDeclaration) \
+ V(CSSVARIABLESRULE, CSSVariablesRule) \
+ V(DOMCOREEXCEPTION, DOMCoreException) \
+ V(DOMIMPLEMENTATION, DOMImplementation) \
+ V(DOMPARSER, DOMParser) \
+ V(DOMSELECTION, DOMSelection) \
+ V(DOMSTRINGLIST, DOMStringList) \
+ V(DOMWINDOW, DOMWindow) \
+ V(EVENT, Event) \
+ V(EVENTEXCEPTION, EventException) \
+ V(FILE, File) \
+ V(FILELIST, FileList) \
+ V(HISTORY, History) \
+ V(UNDETECTABLEHTMLCOLLECTION, UndetectableHTMLCollection) \
+ V(HTMLCOLLECTION, HTMLCollection) \
+ V(HTMLOPTIONSCOLLECTION, HTMLOptionsCollection) \
+ V(IMAGEDATA, ImageData) \
+ V(CANVASPIXELARRAY, CanvasPixelArray) \
+ V(KEYBOARDEVENT, KeyboardEvent) \
+ V(LOCATION, Location) \
+ V(MEDIALIST, MediaList)
+
+#define DOM_OBJECT_TYPES_2(V) \
+ V(MESSAGECHANNEL, MessageChannel) \
+ V(MESSAGEEVENT, MessageEvent) \
+ V(MIMETYPE, MimeType) \
+ V(MIMETYPEARRAY, MimeTypeArray) \
+ V(MOUSEEVENT, MouseEvent) \
+ V(MUTATIONEVENT, MutationEvent) \
+ V(NAMEDNODEMAP, NamedNodeMap) \
+ V(NAVIGATOR, Navigator) \
+ V(NODEFILTER, NodeFilter) \
+ V(NODEITERATOR, NodeIterator) \
+ V(NODELIST, NodeList) \
+ V(OVERFLOWEVENT, OverflowEvent) \
+ V(PLUGIN, Plugin) \
+ V(PLUGINARRAY, PluginArray) \
+ V(PROGRESSEVENT, ProgressEvent) \
+ V(RANGE, Range) \
+ V(RANGEEXCEPTION, RangeException) \
+ V(RECT, Rect) \
+ V(RGBCOLOR, RGBColor) \
+ V(SCREEN, Screen) \
+ V(STYLESHEET, StyleSheet) \
+ V(STYLESHEETLIST, StyleSheetList) \
+ V(TEXTEVENT, TextEvent) \
+ V(TEXTMETRICS, TextMetrics) \
+ V(TREEWALKER, TreeWalker) \
+ V(UIEVENT, UIEvent) \
+ V(WEBKITANIMATIONEVENT, WebKitAnimationEvent) \
+ V(WEBKITCSSKEYFRAMERULE, WebKitCSSKeyframeRule) \
+ V(WEBKITCSSKEYFRAMESRULE, WebKitCSSKeyframesRule) \
+ V(WEBKITCSSMATRIX, WebKitCSSMatrix) \
+ V(WEBKITPOINT, WebKitPoint) \
+ V(WEBKITCSSTRANSFORMVALUE, WebKitCSSTransformValue) \
+ V(WEBKITTRANSITIONEVENT, WebKitTransitionEvent) \
+ V(WHEELEVENT, WheelEvent) \
+ V(XMLHTTPREQUESTUPLOAD, XMLHttpRequestUpload) \
+ V(XMLHTTPREQUESTEXCEPTION, XMLHttpRequestException) \
+ V(XMLHTTPREQUESTPROGRESSEVENT, XMLHttpRequestProgressEvent) \
+ V(XMLSERIALIZER, XMLSerializer) \
+ ACTIVE_DOM_OBJECT_TYPES(V) \
+ VIDEO_NONNODE_TYPES(V) \
+ WORKER_NONNODE_WRAPPER_TYPES(V)
+
+#define DOM_OBJECT_XPATH_TYPES(V) \
+ V(XPATHEVALUATOR, XPathEvaluator) \
+ V(XPATHEXCEPTION, XPathException) \
+ V(XPATHEXPRESSION, XPathExpression) \
+ V(XPATHNSRESOLVER, XPathNSResolver) \
+ V(XPATHRESULT, XPathResult)
+
+#define DOM_OBJECT_DATABASE_TYPES(V) \
+ V(DATABASE, Database) \
+ V(SQLERROR, SQLError) \
+ V(SQLRESULTSET, SQLResultSet) \
+ V(SQLRESULTSETROWLIST, SQLResultSetRowList) \
+ V(SQLTRANSACTION, SQLTransaction)
+
+#if PLATFORM(CHROMIUM)
+#define DOM_OBJECT_TYPES(V) \
+ DOM_OBJECT_TYPES_1(V) \
+ DOM_OBJECT_TYPES_2(V) \
+ DOM_OBJECT_DATABASE_TYPES(V) \
+ DOM_OBJECT_XPATH_TYPES(V) \
+ V(XSLTPROCESSOR, XSLTProcessor) \
+ V(INSPECTORCONTROLLER, InspectorController)
+#endif
+
+#if PLATFORM(ANDROID)
+#define DOM_OBJECT_TYPES(V) \
+ DOM_OBJECT_TYPES_1(V) \
+ DOM_OBJECT_TYPES_2(V) \
+ V(COORDINATES, Coordinates) \
+ V(GEOLOCATION, Geolocation) \
+ V(GEOPOSITION, Geoposition) \
+ V(POSITIONERROR, PositionError) \
+ V(POSITIONERRORCALLBACK, PositionErrorCallback) \
+ V(TOUCHLIST, TouchList) \
+ V(TOUCHEVENT, TouchEvent) \
+ V(TOUCH, Touch) \
+ V(VOIDCALLBACK, VoidCallback)
+#endif
+
+// Other platform must define DOM_OBJECT_TYPES
+
+#if ENABLE(SVG)
+// SVG_OBJECT_TYPES are svg non-node, non-pod types.
+#define SVG_OBJECT_TYPES(V) \
+ V(SVGANGLE, SVGAngle) \
+ V(SVGANIMATEDANGLE, SVGAnimatedAngle) \
+ V(SVGANIMATEDBOOLEAN, SVGAnimatedBoolean) \
+ V(SVGANIMATEDENUMERATION, SVGAnimatedEnumeration) \
+ V(SVGANIMATEDINTEGER, SVGAnimatedInteger) \
+ V(SVGANIMATEDLENGTH, SVGAnimatedLength) \
+ V(SVGANIMATEDLENGTHLIST, SVGAnimatedLengthList) \
+ V(SVGANIMATEDNUMBER, SVGAnimatedNumber) \
+ V(SVGANIMATEDNUMBERLIST, SVGAnimatedNumberList) \
+ V(SVGANIMATEDPRESERVEASPECTRATIO, SVGAnimatedPreserveAspectRatio) \
+ V(SVGANIMATEDRECT, SVGAnimatedRect) \
+ V(SVGANIMATEDSTRING, SVGAnimatedString) \
+ V(SVGANIMATEDTRANSFORMLIST, SVGAnimatedTransformList) \
+ V(SVGCOLOR, SVGColor) \
+ V(SVGELEMENTINSTANCE, SVGElementInstance) \
+ V(SVGELEMENTINSTANCELIST, SVGElementInstanceList) \
+ V(SVGEXCEPTION, SVGException) \
+ V(SVGLENGTHLIST, SVGLengthList) \
+ V(SVGNUMBERLIST, SVGNumberList) \
+ V(SVGPAINT, SVGPaint) \
+ V(SVGPATHSEG, SVGPathSeg) \
+ V(SVGPATHSEGARCABS, SVGPathSegArcAbs) \
+ V(SVGPATHSEGARCREL, SVGPathSegArcRel) \
+ V(SVGPATHSEGCLOSEPATH, SVGPathSegClosePath) \
+ V(SVGPATHSEGCURVETOCUBICABS, SVGPathSegCurvetoCubicAbs) \
+ V(SVGPATHSEGCURVETOCUBICREL, SVGPathSegCurvetoCubicRel) \
+ V(SVGPATHSEGCURVETOCUBICSMOOTHABS, SVGPathSegCurvetoCubicSmoothAbs) \
+ V(SVGPATHSEGCURVETOCUBICSMOOTHREL, SVGPathSegCurvetoCubicSmoothRel) \
+ V(SVGPATHSEGCURVETOQUADRATICABS, SVGPathSegCurvetoQuadraticAbs) \
+ V(SVGPATHSEGCURVETOQUADRATICREL, SVGPathSegCurvetoQuadraticRel) \
+ V(SVGPATHSEGCURVETOQUADRATICSMOOTHABS, SVGPathSegCurvetoQuadraticSmoothAbs)\
+ V(SVGPATHSEGCURVETOQUADRATICSMOOTHREL, SVGPathSegCurvetoQuadraticSmoothRel)\
+ V(SVGPATHSEGLINETOABS, SVGPathSegLinetoAbs) \
+ V(SVGPATHSEGLINETOHORIZONTALABS, SVGPathSegLinetoHorizontalAbs) \
+ V(SVGPATHSEGLINETOHORIZONTALREL, SVGPathSegLinetoHorizontalRel) \
+ V(SVGPATHSEGLINETOREL, SVGPathSegLinetoRel) \
+ V(SVGPATHSEGLINETOVERTICALABS, SVGPathSegLinetoVerticalAbs) \
+ V(SVGPATHSEGLINETOVERTICALREL, SVGPathSegLinetoVerticalRel) \
+ V(SVGPATHSEGLIST, SVGPathSegList) \
+ V(SVGPATHSEGMOVETOABS, SVGPathSegMovetoAbs) \
+ V(SVGPATHSEGMOVETOREL, SVGPathSegMovetoRel) \
+ V(SVGPOINTLIST, SVGPointList) \
+ V(SVGPRESERVEASPECTRATIO, SVGPreserveAspectRatio) \
+ V(SVGRENDERINGINTENT, SVGRenderingIntent) \
+ V(SVGSTRINGLIST, SVGStringList) \
+ V(SVGTRANSFORMLIST, SVGTransformList) \
+ V(SVGUNITTYPES, SVGUnitTypes) \
+ V(SVGZOOMEVENT, SVGZoomEvent)
+
+// SVG POD types should list all types whose IDL has PODType declaration.
+#define SVG_POD_TYPES(V) \
+ V(SVGLENGTH, SVGLength) \
+ V(SVGTRANSFORM, SVGTransform) \
+ V(SVGMATRIX, SVGMatrix) \
+ V(SVGNUMBER, SVGNumber) \
+ V(SVGPOINT, SVGPoint) \
+ V(SVGRECT, SVGRect)
+
+// POD types can have different implementation names, see CodeGenerateV8.pm.
+#define SVG_POD_NATIVE_TYPES(V) \
+ V(SVGLENGTH, SVGLength) \
+ V(SVGTRANSFORM, SVGTransform) \
+ V(SVGMATRIX, TransformationMatrix) \
+ V(SVGNUMBER, float) \
+ V(SVGPOINT, FloatPoint) \
+ V(SVGRECT, FloatRect)
+
+// Shouldn't generate code for these two types.
+#define SVG_NO_WRAPPER_TYPES(V) \
+ V(SVGURIREFERENCE, SVGURIReference) \
+ V(SVGANIMATEDPOINTS, SVGAnimatedPoints)
+
+// SVG_NONNODE_TYPES are SVG non-node object types, pod typs and
+// numerical types.
+#define SVG_NONNODE_TYPES(V) \
+ SVG_OBJECT_TYPES(V) \
+ SVG_POD_TYPES(V)
+#endif // SVG
+
+// EVENTTARGET, EVENTLISTENER, and NPOBJECT do not have V8 wrappers.
+#define DOM_NO_WRAPPER_TYPES(V) \
+ V(EVENTTARGET, EventTarget) \
+ V(EVENTLISTENER, EventListener) \
+ V(NPOBJECT, NPObject)
+
+#if ENABLE(SVG)
+#define WRAPPER_TYPES(V) \
+ DOM_NODE_TYPES(V) \
+ DOM_OBJECT_TYPES(V) \
+ SVG_NODE_TYPES(V) \
+ SVG_NONNODE_TYPES(V)
+#define NO_WRAPPER_TYPES(V) \
+ DOM_NO_WRAPPER_TYPES(V) \
+ SVG_NO_WRAPPER_TYPES(V)
+#else // SVG
+#define WRAPPER_TYPES(V) \
+ DOM_NODE_TYPES(V) \
+ DOM_OBJECT_TYPES(V)
+#define NO_WRAPPER_TYPES(V) \
+ DOM_NO_WRAPPER_TYPES(V)
+#endif // SVG
+
+#define ALL_WRAPPER_TYPES(V) \
+ WRAPPER_TYPES(V) \
+ NO_WRAPPER_TYPES(V)
+
+class V8ClassIndex {
+ public:
+ // Type must start at non-negative numbers. See ToInt, FromInt.
+ enum V8WrapperType {
+ INVALID_CLASS_INDEX = 0,
+#define DEFINE_ENUM(name, type) name,
+ ALL_WRAPPER_TYPES(DEFINE_ENUM)
+#undef DEFINE_ENUM
+ CLASSINDEX_END,
+ WRAPPER_TYPE_COUNT = CLASSINDEX_END
+ };
+
+ static int ToInt(V8WrapperType type) { return static_cast<int>(type); }
+
+ static V8WrapperType FromInt(int v) {
+ ASSERT(INVALID_CLASS_INDEX <= v && v < CLASSINDEX_END);
+ return static_cast<V8WrapperType>(v);
+ }
+
+ static FunctionTemplateFactory GetFactory(V8WrapperType type);
+ // Returns a field to be used as cache for the template for the given type
+ static v8::Persistent<v8::FunctionTemplate>* GetCache(V8WrapperType type);
+};
+
+}
+
+#endif // V8_INDEX_H__
diff --git a/V8Binding/v8/v8_npobject.h b/V8Binding/v8/v8_npobject.h
new file mode 100644
index 0000000..c2d8550
--- /dev/null
+++ b/V8Binding/v8/v8_npobject.h
@@ -0,0 +1,7 @@
+// 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.
+
+// This is a temporary file until V8HTMLPlugInElementCustom.cpp in WebKit
+// includes the new name of this file.
+#include "V8NPObject.h"
diff --git a/V8Binding/v8/v8_proxy.cpp b/V8Binding/v8/v8_proxy.cpp
new file mode 100644
index 0000000..204b2bc
--- /dev/null
+++ b/V8Binding/v8/v8_proxy.cpp
@@ -0,0 +1,3392 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#include <algorithm>
+#include <utility>
+
+#include <v8.h>
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+#include <v8-debug.h>
+#endif
+
+#include "v8_proxy.h"
+#include "v8_index.h"
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "V8Collection.h"
+#include "V8DOMWindow.h"
+
+#if PLATFORM(CHROMIUM)
+#include "ChromiumBridge.h"
+#endif
+
+#include "DOMObjectsInclude.h"
+
+#include "ScriptController.h"
+#include "V8DOMMap.h"
+
+#include "CString.h"
+
+namespace WebCore {
+
+V8EventListenerList::V8EventListenerList(const char* name)
+{
+ ASSERT(strlen(name) <= kMaxKeyNameLength);
+ v8::HandleScope handleScope;
+
+ // Write the name into a temporary buffer, leaving 1 space at the beginning
+ // for a prefix we'll vary between the inline and non-inline keys.
+ char keyBuffer[kMaxKeyNameLength + 2] = { 0 };
+ strncpy(keyBuffer + 1, name, kMaxKeyNameLength);
+ keyBuffer[0] = '1';
+ m_inlineKey = v8::Persistent<v8::String>::New(v8::String::New(keyBuffer));
+ keyBuffer[0] = '2';
+ m_nonInlineKey = v8::Persistent<v8::String>::New(v8::String::New(keyBuffer));
+}
+
+V8EventListenerList::~V8EventListenerList()
+{
+ m_inlineKey.Dispose();
+ m_nonInlineKey.Dispose();
+}
+
+V8EventListenerList::iterator V8EventListenerList::begin()
+{
+ return m_list.begin();
+}
+
+V8EventListenerList::iterator V8EventListenerList::end()
+{
+ return m_list.end();
+}
+
+v8::Handle<v8::String> V8EventListenerList::getKey(bool isInline)
+{
+ if (isInline)
+ return m_inlineKey;
+ else
+ return m_nonInlineKey;
+}
+
+// See comment in .h file for this function, and update accordingly if
+// implementation details change here.
+void V8EventListenerList::add(V8EventListener* listener)
+{
+ m_list.append(listener);
+
+ v8::HandleScope handleScope;
+ v8::Local<v8::Object> object = listener->getListenerObject();
+ v8::Local<v8::Value> value = v8::External::Wrap(listener);
+ object->SetHiddenValue(getKey(listener->isInline()), value);
+}
+
+void V8EventListenerList::remove(V8EventListener* listener)
+{
+ v8::HandleScope handleScope;
+ for (size_t i = 0; i < m_list.size(); i++) {
+ V8EventListener* element = m_list.at(i);
+ if (element->isInline() == listener->isInline() && element == listener) {
+ v8::Local<v8::Object> object = listener->getListenerObject();
+ object->DeleteHiddenValue(getKey(listener->isInline()));
+ m_list.remove(i);
+ break;
+ }
+ }
+}
+
+void V8EventListenerList::clear()
+{
+ v8::HandleScope handleScope;
+ for (size_t i = 0; i < m_list.size(); i++) {
+ V8EventListener* element = m_list.at(i);
+ v8::Local<v8::Object> object = element->getListenerObject();
+ object->DeleteHiddenValue(getKey(element->isInline()));
+ }
+ m_list.clear();
+}
+
+V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool isInline)
+{
+ v8::Local<v8::Value> value = object->GetHiddenValue(getKey(isInline));
+ if (value.IsEmpty())
+ return 0;
+ return reinterpret_cast<V8EventListener*>(v8::External::Unwrap(value));
+}
+
+
+// Static utility context.
+v8::Persistent<v8::Context> V8Proxy::m_utilityContext;
+
+// Static list of registered extensions
+V8ExtensionList V8Proxy::m_extensions;
+
+
+#ifndef NDEBUG
+// Keeps track of global handles created (not JS wrappers
+// of DOM objects). Often these global handles are source
+// of leaks.
+//
+// If you want to let a C++ object hold a persistent handle
+// to a JS object, you should register the handle here to
+// keep track of leaks.
+//
+// When creating a persistent handle, call:
+//
+// #ifndef NDEBUG
+// V8Proxy::RegisterGlobalHandle(type, host, handle);
+// #endif
+//
+// When releasing the handle, call:
+//
+// #ifndef NDEBUG
+// V8Proxy::UnregisterGlobalHandle(type, host, handle);
+// #endif
+//
+typedef HashMap<v8::Value*, GlobalHandleInfo*> GlobalHandleMap;
+
+static GlobalHandleMap& global_handle_map()
+{
+ static GlobalHandleMap static_global_handle_map;
+ return static_global_handle_map;
+}
+
+
+// The USE_VAR(x) template is used to silence C++ compiler warnings
+// issued for unused variables (typically parameters or values that
+// we want to watch in the debugger).
+template <typename T>
+static inline void USE_VAR(T) { }
+
+// The function is the place to set the break point to inspect
+// live global handles. Leaks are often come from leaked global handles.
+static void EnumerateGlobalHandles()
+{
+ for (GlobalHandleMap::iterator it = global_handle_map().begin(),
+ end = global_handle_map().end(); it != end; ++it) {
+ GlobalHandleInfo* info = it->second;
+ USE_VAR(info);
+ v8::Value* handle = it->first;
+ USE_VAR(handle);
+ }
+}
+
+void V8Proxy::RegisterGlobalHandle(GlobalHandleType type, void* host,
+ v8::Persistent<v8::Value> handle)
+{
+ ASSERT(!global_handle_map().contains(*handle));
+ global_handle_map().set(*handle, new GlobalHandleInfo(host, type));
+}
+
+
+void V8Proxy::UnregisterGlobalHandle(void* host, v8::Persistent<v8::Value> handle)
+{
+ ASSERT(global_handle_map().contains(*handle));
+ GlobalHandleInfo* info = global_handle_map().take(*handle);
+ ASSERT(info->host_ == host);
+ delete info;
+}
+#endif // ifndef NDEBUG
+
+void BatchConfigureAttributes(v8::Handle<v8::ObjectTemplate> inst,
+ v8::Handle<v8::ObjectTemplate> proto,
+ const BatchedAttribute* attrs,
+ size_t num_attrs)
+{
+ for (size_t i = 0; i < num_attrs; ++i) {
+ const BatchedAttribute* a = &attrs[i];
+ (a->on_proto ? proto : inst)->SetAccessor(
+ v8::String::New(a->name),
+ a->getter,
+ a->setter,
+ a->data == V8ClassIndex::INVALID_CLASS_INDEX
+ ? v8::Handle<v8::Value>()
+ : v8::Integer::New(V8ClassIndex::ToInt(a->data)),
+ a->settings,
+ a->attribute);
+ }
+}
+
+void BatchConfigureConstants(v8::Handle<v8::FunctionTemplate> desc,
+ v8::Handle<v8::ObjectTemplate> proto,
+ const BatchedConstant* consts,
+ size_t num_consts)
+{
+ for (size_t i = 0; i < num_consts; ++i) {
+ const BatchedConstant* c = &consts[i];
+ desc->Set(v8::String::New(c->name),
+ v8::Integer::New(c->value),
+ v8::ReadOnly);
+ proto->Set(v8::String::New(c->name),
+ v8::Integer::New(c->value),
+ v8::ReadOnly);
+ }
+}
+
+typedef HashMap<Node*, v8::Object*> DOMNodeMap;
+typedef HashMap<void*, v8::Object*> DOMObjectMap;
+
+#ifndef NDEBUG
+static void EnumerateDOMObjectMap(DOMObjectMap& wrapper_map)
+{
+ for (DOMObjectMap::iterator it = wrapper_map.begin(), end = wrapper_map.end();
+ it != end; ++it) {
+ v8::Persistent<v8::Object> wrapper(it->second);
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ void* obj = it->first;
+ USE_VAR(type);
+ USE_VAR(obj);
+ }
+}
+
+
+static void EnumerateDOMNodeMap(DOMNodeMap& node_map)
+{
+ for (DOMNodeMap::iterator it = node_map.begin(), end = node_map.end();
+ it != end; ++it) {
+ Node* node = it->first;
+ USE_VAR(node);
+ ASSERT(v8::Persistent<v8::Object>(it->second).IsWeak());
+ }
+}
+#endif // NDEBUG
+
+#if ENABLE(SVG)
+v8::Handle<v8::Value> V8Proxy::SVGElementInstanceToV8Object(
+ SVGElementInstance* instance)
+{
+ if (!instance)
+ return v8::Null();
+
+ v8::Handle<v8::Object> existing_instance = getDOMSVGElementInstanceMap().get(instance);
+ if (!existing_instance.IsEmpty())
+ return existing_instance;
+
+ instance->ref();
+
+ // Instantiate the V8 object and remember it
+ v8::Handle<v8::Object> result =
+ InstantiateV8Object(V8ClassIndex::SVGELEMENTINSTANCE,
+ V8ClassIndex::SVGELEMENTINSTANCE,
+ instance);
+ if (!result.IsEmpty()) {
+ // Only update the DOM SVG element map if the result is non-empty.
+ getDOMSVGElementInstanceMap().set(instance,
+ v8::Persistent<v8::Object>::New(result));
+ }
+ return result;
+}
+
+// Map of SVG objects with contexts to their contexts
+static HashMap<void*, SVGElement*>& svg_object_to_context_map()
+{
+ static HashMap<void*, SVGElement*> static_svg_object_to_context_map;
+ return static_svg_object_to_context_map;
+}
+
+v8::Handle<v8::Value> V8Proxy::SVGObjectWithContextToV8Object(
+ V8ClassIndex::V8WrapperType type, void* object)
+{
+ if (!object)
+ return v8::Null();
+
+ v8::Persistent<v8::Object> result =
+ getDOMSVGObjectWithContextMap().get(object);
+ if (!result.IsEmpty()) return result;
+
+ // Special case: SVGPathSegs need to be downcast to their real type
+ if (type == V8ClassIndex::SVGPATHSEG)
+ type = V8Custom::DowncastSVGPathSeg(object);
+
+ v8::Local<v8::Object> v8obj = InstantiateV8Object(type, type, object);
+ if (!v8obj.IsEmpty()) {
+ result = v8::Persistent<v8::Object>::New(v8obj);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: static_cast<NAME*>(object)->ref(); break;
+SVG_OBJECT_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: \
+ static_cast<V8SVGPODTypeWrapper<NAME>*>(object)->ref(); break;
+SVG_POD_NATIVE_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default:
+ ASSERT(false);
+ }
+ getDOMSVGObjectWithContextMap().set(object, result);
+ }
+
+ return result;
+}
+
+void V8Proxy::SetSVGContext(void* obj, SVGElement* context)
+{
+ SVGElement* old_context = svg_object_to_context_map().get(obj);
+
+ if (old_context == context)
+ return;
+
+ if (old_context)
+ old_context->deref();
+
+ if (context)
+ context->ref();
+
+ svg_object_to_context_map().set(obj, context);
+}
+
+SVGElement* V8Proxy::GetSVGContext(void* obj)
+{
+ return svg_object_to_context_map().get(obj);
+}
+
+#endif
+
+// A map from a DOM node to its JS wrapper, the wrapper
+// is kept as a strong reference to survive GCs.
+static DOMObjectMap& gc_protected_map() {
+ static DOMObjectMap static_gc_protected_map;
+ return static_gc_protected_map;
+}
+
+// static
+void V8Proxy::GCProtect(void* dom_object)
+{
+ if (!dom_object)
+ return;
+ if (gc_protected_map().contains(dom_object))
+ return;
+ if (!getDOMObjectMap().contains(dom_object))
+ return;
+
+ // Create a new (strong) persistent handle for the object.
+ v8::Persistent<v8::Object> wrapper = getDOMObjectMap().get(dom_object);
+ if (wrapper.IsEmpty()) return;
+
+ gc_protected_map().set(dom_object, *v8::Persistent<v8::Object>::New(wrapper));
+}
+
+
+// static
+void V8Proxy::GCUnprotect(void* dom_object)
+{
+ if (!dom_object)
+ return;
+ if (!gc_protected_map().contains(dom_object))
+ return;
+
+ // Dispose the strong reference.
+ v8::Persistent<v8::Object> wrapper(gc_protected_map().take(dom_object));
+ wrapper.Dispose();
+}
+
+
+typedef std::pair<uintptr_t, Node*> GrouperPair;
+typedef Vector<GrouperPair> GrouperList;
+
+#if PLATFORM(ANDROID)
+// Sort GrouperPair by the group id. Node* is only involved to sort within
+// a group id, so it will be fine.
+static bool ComparePair(const GrouperPair& p1, const GrouperPair& p2) {
+ return p1.first < p2.first;
+}
+#endif
+
+// Create object groups for DOM tree nodes.
+static void GCPrologue()
+{
+ v8::HandleScope scope;
+
+#ifndef NDEBUG
+ EnumerateDOMObjectMap(getDOMObjectMap().impl());
+#endif
+
+ // Run through all objects with possible pending activity making their
+ // wrappers non weak if there is pending activity.
+ DOMObjectMap active_map = getActiveDOMObjectMap().impl();
+ for (DOMObjectMap::iterator it = active_map.begin(), end = active_map.end();
+ it != end; ++it) {
+ void* obj = it->first;
+ v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>(it->second);
+ ASSERT(wrapper.IsWeak());
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: { \
+ NAME* impl = static_cast<NAME*>(obj); \
+ if (impl->hasPendingActivity()) \
+ wrapper.ClearWeak(); \
+ break; \
+ }
+ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ default:
+ ASSERT(false);
+#undef MAKE_CASE
+ }
+
+ // Additional handling of message port ensuring that entangled ports also
+ // have their wrappers entangled. This should ideally be handled when the
+ // ports are actually entangled in MessagePort::entangle, but to avoid
+ // forking MessagePort.* this is postponed to GC time. Having this postponed
+ // has the drawback that the wrappers are "entangled/unentangled" for each
+ // GC even though their entnaglement most likely is still the same.
+ if (type == V8ClassIndex::MESSAGEPORT) {
+ // Get the port and its entangled port.
+ MessagePort* port1 = static_cast<MessagePort*>(obj);
+ MessagePort* port2 = port1->entangledPort();
+ if (port2 != NULL) {
+ // As ports are always entangled in pairs only perform the entanglement
+ // once for each pair (see ASSERT in MessagePort::unentangle()).
+ if (port1 < port2) {
+ v8::Handle<v8::Value> port1_wrapper =
+ V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port1);
+ v8::Handle<v8::Value> port2_wrapper =
+ V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port2);
+ ASSERT(port1_wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(port1_wrapper)->SetInternalField(
+ V8Custom::kMessagePortEntangledPortIndex, port2_wrapper);
+ ASSERT(port2_wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(port2_wrapper)->SetInternalField(
+ V8Custom::kMessagePortEntangledPortIndex, port1_wrapper);
+ }
+ } else {
+ // Remove the wrapper entanglement when a port is not entangled.
+ if (V8Proxy::DOMObjectHasJSWrapper(port1)) {
+ v8::Handle<v8::Value> wrapper =
+ V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port1);
+ ASSERT(wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(wrapper)->SetInternalField(
+ V8Custom::kMessagePortEntangledPortIndex, v8::Undefined());
+ }
+ }
+ }
+ }
+
+ // Create object groups.
+ DOMNodeMap node_map = getDOMNodeMap().impl();
+ GrouperList grouper;
+ grouper.reserveCapacity(node_map.size());
+
+ for (DOMNodeMap::iterator it = node_map.begin(), end = node_map.end();
+ it != end; ++it) {
+ Node* node = it->first;
+
+ // If the node is in document, put it in the ownerDocument's object group.
+ //
+ // If an image element was created by JavaScript "new Image",
+ // it is not in a document. However, if the load event has not
+ // been fired (still onloading), it is treated as in the document.
+ //
+ // Otherwise, the node is put in an object group identified by the root
+ // elment of the tree to which it belongs.
+ uintptr_t group_id;
+ if (node->inDocument() ||
+ (node->hasTagName(HTMLNames::imgTag) &&
+ !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent())) {
+ group_id = reinterpret_cast<uintptr_t>(node->document());
+ } else {
+ Node* root = node;
+ while (root->parent())
+ root = root->parent();
+
+ // If the node is alone in its DOM tree (doesn't have a parent or any
+ // children) then the group will be filtered out later anyway.
+ if (root == node && !node->hasChildNodes())
+ continue;
+
+ group_id = reinterpret_cast<uintptr_t>(root);
+ }
+ grouper.append(GrouperPair(group_id, node));
+ }
+
+#if PLATFORM(ANDROID)
+ std::stable_sort<GrouperPair>(grouper.begin(), grouper.end(), ComparePair);
+#else
+ // Group by sorting by the group id. This will use the std::pair operator<,
+ // which will really sort by both the group id and the Node*. However the
+ // Node* is only involved to sort within a group id, so it will be fine.
+ std::sort(grouper.begin(), grouper.end());
+#endif
+
+ // TODO(deanm): Should probably work in iterators here, but indexes were
+ // easier for my simple mind.
+ for (size_t i = 0; i < grouper.size(); ) {
+ // Seek to the next key (or the end of the list).
+ size_t next_key_index = grouper.size();
+ for (size_t j = i; j < grouper.size(); ++j) {
+ if (grouper[i].first != grouper[j].first) {
+ next_key_index = j;
+ break;
+ }
+ }
+
+ ASSERT(next_key_index > i);
+
+ // We only care about a group if it has more than one object. If it only
+ // has one object, it has nothing else that needs to be kept alive.
+ if (next_key_index - i <= 1) {
+ i = next_key_index;
+ continue;
+ }
+
+ Vector<v8::Persistent<v8::Value> > group;
+ group.reserveCapacity(next_key_index - i);
+ for (; i < next_key_index; ++i) {
+ v8::Persistent<v8::Value> wrapper =
+ getDOMNodeMap().get(grouper[i].second);
+ if (!wrapper.IsEmpty())
+ group.append(wrapper);
+ }
+
+ if (group.size() > 1)
+ v8::V8::AddObjectGroup(&group[0], group.size());
+
+ ASSERT(i == next_key_index);
+ }
+}
+
+
+static void GCEpilogue()
+{
+ v8::HandleScope scope;
+
+ // Run through all objects with pending activity making their wrappers weak
+ // again.
+ DOMObjectMap active_map = getActiveDOMObjectMap().impl();
+ for (DOMObjectMap::iterator it = active_map.begin(), end = active_map.end();
+ it != end; ++it) {
+ void* obj = it->first;
+ v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>(it->second);
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: { \
+ NAME* impl = static_cast<NAME*>(obj); \
+ if (impl->hasPendingActivity()) { \
+ ASSERT(!wrapper.IsWeak()); \
+ wrapper.MakeWeak(impl, &weakActiveDOMObjectCallback); \
+ } \
+ break; \
+ }
+ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ default:
+ ASSERT(false);
+#undef MAKE_CASE
+ }
+ }
+
+#ifndef NDEBUG
+ // Check all survivals are weak.
+ EnumerateDOMObjectMap(getDOMObjectMap().impl());
+ EnumerateDOMNodeMap(getDOMNodeMap().impl());
+ EnumerateDOMObjectMap(gc_protected_map());
+ EnumerateGlobalHandles();
+#undef USE_VAR
+#endif
+}
+
+
+typedef HashMap<int, v8::FunctionTemplate*> FunctionTemplateMap;
+
+bool AllowAllocation::m_current = false;
+
+
+// JavaScriptConsoleMessages encapsulate everything needed to
+// log messages originating from JavaScript to the Chrome console.
+class JavaScriptConsoleMessage {
+ public:
+ JavaScriptConsoleMessage(const String& str,
+ const String& sourceID,
+ unsigned lineNumber)
+ : m_string(str)
+ , m_sourceID(sourceID)
+ , m_lineNumber(lineNumber) { }
+
+ void AddToPage(Page* page) const;
+
+ private:
+ const String m_string;
+ const String m_sourceID;
+ const unsigned m_lineNumber;
+};
+
+void JavaScriptConsoleMessage::AddToPage(Page* page) const
+{
+ ASSERT(page);
+ Console* console = page->mainFrame()->domWindow()->console();
+ console->addMessage(JSMessageSource, ErrorMessageLevel, m_string, m_lineNumber, m_sourceID);
+}
+
+// The ConsoleMessageManager handles all console messages that stem
+// from JavaScript. It keeps a list of messages that have been delayed but
+// it makes sure to add all messages to the console in the right order.
+class ConsoleMessageManager {
+ public:
+ // Add a message to the console. May end up calling JavaScript code
+ // indirectly through the inspector so only call this function when
+ // it is safe to do allocations.
+ static void AddMessage(Page* page, const JavaScriptConsoleMessage& message);
+
+ // Add a message to the console but delay the reporting until it
+ // is safe to do so: Either when we leave JavaScript execution or
+ // when adding other console messages. The primary purpose of this
+ // method is to avoid calling into V8 to handle console messages
+ // when the VM is in a state that does not support GCs or allocations.
+ // Delayed messages are always reported in the page corresponding
+ // to the active context.
+ static void AddDelayedMessage(const JavaScriptConsoleMessage& message);
+
+ // Process any delayed messages. May end up calling JavaScript code
+ // indirectly through the inspector so only call this function when
+ // it is safe to do allocations.
+ static void ProcessDelayedMessages();
+
+ private:
+ // All delayed messages are stored in this vector. If the vector
+ // is NULL, there are no delayed messages.
+ static Vector<JavaScriptConsoleMessage>* m_delayed;
+};
+
+
+Vector<JavaScriptConsoleMessage>* ConsoleMessageManager::m_delayed = NULL;
+
+
+void ConsoleMessageManager::AddMessage(
+ Page* page,
+ const JavaScriptConsoleMessage& message)
+{
+ // Process any delayed messages to make sure that messages
+ // appear in the right order in the console.
+ ProcessDelayedMessages();
+ message.AddToPage(page);
+}
+
+
+void ConsoleMessageManager::AddDelayedMessage(const JavaScriptConsoleMessage& message)
+{
+ if (!m_delayed)
+ // Allocate a vector for the delayed messages. Will be
+ // deallocated when the delayed messages are processed
+ // in ProcessDelayedMessages().
+ m_delayed = new Vector<JavaScriptConsoleMessage>();
+ m_delayed->append(message);
+}
+
+
+void ConsoleMessageManager::ProcessDelayedMessages()
+{
+ // If we have a delayed vector it cannot be empty.
+ if (!m_delayed)
+ return;
+ ASSERT(!m_delayed->isEmpty());
+
+ // Add the delayed messages to the page of the active
+ // context. If that for some bizarre reason does not
+ // exist, we clear the list of delayed messages to avoid
+ // posting messages. We still deallocate the vector.
+ Frame* frame = V8Proxy::retrieveActiveFrame();
+ Page* page = NULL;
+ if (frame)
+ page = frame->page();
+ if (!page)
+ m_delayed->clear();
+
+ // Iterate through all the delayed messages and add them
+ // to the console.
+ const int size = m_delayed->size();
+ for (int i = 0; i < size; i++) {
+ m_delayed->at(i).AddToPage(page);
+ }
+
+ // Deallocate the delayed vector.
+ delete m_delayed;
+ m_delayed = NULL;
+}
+
+
+// Convenience class for ensuring that delayed messages in the
+// ConsoleMessageManager are processed quickly.
+class ConsoleMessageScope {
+ public:
+ ConsoleMessageScope() { ConsoleMessageManager::ProcessDelayedMessages(); }
+ ~ConsoleMessageScope() { ConsoleMessageManager::ProcessDelayedMessages(); }
+};
+
+void log_info(Frame* frame, const String& msg, const String& url)
+{
+ Page* page = frame->page();
+ if (!page)
+ return;
+ JavaScriptConsoleMessage message(msg, url, 0);
+ ConsoleMessageManager::AddMessage(page, message);
+}
+
+static void HandleConsoleMessage(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data)
+{
+ // Use the frame where JavaScript is called from.
+ Frame* frame = V8Proxy::retrieveActiveFrame();
+ if (!frame)
+ return;
+
+ Page* page = frame->page();
+ if (!page)
+ return;
+
+ v8::Handle<v8::String> errorMessageString = message->Get();
+ ASSERT(!errorMessageString.IsEmpty());
+ String errorMessage = ToWebCoreString(errorMessageString);
+
+ v8::Handle<v8::Value> resourceName = message->GetScriptResourceName();
+ bool useURL = (resourceName.IsEmpty() || !resourceName->IsString());
+ String resourceNameString = (useURL)
+ ? frame->document()->url()
+ : ToWebCoreString(resourceName);
+ JavaScriptConsoleMessage consoleMessage(errorMessage,
+ resourceNameString,
+ message->GetLineNumber());
+ ConsoleMessageManager::AddMessage(page, consoleMessage);
+}
+
+
+enum DelayReporting {
+ REPORT_LATER,
+ REPORT_NOW
+};
+
+
+static void ReportUnsafeAccessTo(Frame* target, DelayReporting delay)
+{
+ ASSERT(target);
+ Document* targetDocument = target->document();
+ if (!targetDocument)
+ return;
+
+ Frame* source = V8Proxy::retrieveActiveFrame();
+ if (!source || !source->document())
+ return; // Ignore error if the source document is gone.
+
+ Document* sourceDocument = source->document();
+
+ // FIXME: This error message should contain more specifics of why the same
+ // origin check has failed.
+ String str = String::format("Unsafe JavaScript attempt to access frame "
+ "with URL %s from frame with URL %s. "
+ "Domains, protocols and ports must match.\n",
+ targetDocument->url().string().utf8().data(),
+ sourceDocument->url().string().utf8().data());
+
+ // Build a console message with fake source ID and line number.
+ const String kSourceID = "";
+ const int kLineNumber = 1;
+ JavaScriptConsoleMessage message(str, kSourceID, kLineNumber);
+
+ if (delay == REPORT_NOW) {
+ // NOTE(tc): Apple prints the message in the target page, but it seems like
+ // it should be in the source page. Even for delayed messages, we put it in
+ // the source page; see ConsoleMessageManager::ProcessDelayedMessages().
+ ConsoleMessageManager::AddMessage(source->page(), message);
+
+ } else {
+ ASSERT(delay == REPORT_LATER);
+ // We cannot safely report the message eagerly, because this may cause
+ // allocations and GCs internally in V8 and we cannot handle that at this
+ // point. Therefore we delay the reporting.
+ ConsoleMessageManager::AddDelayedMessage(message);
+ }
+}
+
+static void ReportUnsafeJavaScriptAccess(v8::Local<v8::Object> host,
+ v8::AccessType type,
+ v8::Local<v8::Value> data)
+{
+ Frame* target = V8Custom::GetTargetFrame(host, data);
+ if (target)
+ ReportUnsafeAccessTo(target, REPORT_LATER);
+}
+
+static void HandleFatalErrorInV8()
+{
+ // TODO: We temporarily deal with V8 internal error situations
+ // such as out-of-memory by crashing the renderer.
+ CRASH();
+}
+
+static void ReportFatalErrorInV8(const char* location, const char* message)
+{
+ // V8 is shutdown, we cannot use V8 api.
+ // The only thing we can do is to disable JavaScript.
+ // TODO: clean up V8Proxy and disable JavaScript.
+ printf("V8 error: %s (%s)\n", message, location);
+ HandleFatalErrorInV8();
+}
+
+V8Proxy::~V8Proxy()
+{
+ clearForClose();
+ DestroyGlobal();
+}
+
+void V8Proxy::DestroyGlobal()
+{
+ if (!m_global.IsEmpty()) {
+#ifndef NDEBUG
+ UnregisterGlobalHandle(this, m_global);
+#endif
+ m_global.Dispose();
+ m_global.Clear();
+ }
+}
+
+
+bool V8Proxy::DOMObjectHasJSWrapper(void* obj) {
+ return getDOMObjectMap().contains(obj) ||
+ getActiveDOMObjectMap().contains(obj);
+}
+
+
+// The caller must have increased obj's ref count.
+void V8Proxy::SetJSWrapperForDOMObject(void* obj, v8::Persistent<v8::Object> wrapper)
+{
+ ASSERT(MaybeDOMWrapper(wrapper));
+#ifndef NDEBUG
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE:
+ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ ASSERT(false);
+#undef MAKE_CASE
+ default: break;
+ }
+#endif
+ getDOMObjectMap().set(obj, wrapper);
+}
+
+// The caller must have increased obj's ref count.
+void V8Proxy::SetJSWrapperForActiveDOMObject(void* obj, v8::Persistent<v8::Object> wrapper)
+{
+ ASSERT(MaybeDOMWrapper(wrapper));
+#ifndef NDEBUG
+ V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(wrapper);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: break;
+ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ default: ASSERT(false);
+#undef MAKE_CASE
+ }
+#endif
+ getActiveDOMObjectMap().set(obj, wrapper);
+}
+
+// The caller must have increased node's ref count.
+void V8Proxy::SetJSWrapperForDOMNode(Node* node, v8::Persistent<v8::Object> wrapper)
+{
+ ASSERT(MaybeDOMWrapper(wrapper));
+ getDOMNodeMap().set(node, wrapper);
+}
+
+PassRefPtr<EventListener> V8Proxy::createInlineEventListener(
+ const String& functionName,
+ const String& code, Node* node)
+{
+ return V8LazyEventListener::create(m_frame, code, functionName);
+}
+
+#if ENABLE(SVG)
+PassRefPtr<EventListener> V8Proxy::createSVGEventHandler(const String& functionName,
+ const String& code, Node* node)
+{
+ return V8LazyEventListener::create(m_frame, code, functionName);
+}
+#endif
+
+
+// Event listeners
+
+static V8EventListener* FindEventListenerInList(V8EventListenerList& list,
+ v8::Local<v8::Value> listener,
+ bool isInline)
+{
+ ASSERT(v8::Context::InContext());
+
+ if (!listener->IsObject())
+ return 0;
+
+ return list.find(listener->ToObject(), isInline);
+}
+
+// Find an existing wrapper for a JS event listener in the map.
+PassRefPtr<V8EventListener> V8Proxy::FindV8EventListener(v8::Local<v8::Value> listener,
+ bool isInline)
+{
+ return FindEventListenerInList(m_event_listeners, listener, isInline);
+}
+
+PassRefPtr<V8EventListener> V8Proxy::FindOrCreateV8EventListener(v8::Local<v8::Value> obj, bool isInline)
+{
+ ASSERT(v8::Context::InContext());
+
+ if (!obj->IsObject())
+ return 0;
+
+ V8EventListener* wrapper =
+ FindEventListenerInList(m_event_listeners, obj, isInline);
+ if (wrapper)
+ return wrapper;
+
+ // Create a new one, and add to cache.
+ RefPtr<V8EventListener> new_listener =
+ V8EventListener::create(m_frame, v8::Local<v8::Object>::Cast(obj), isInline);
+ m_event_listeners.add(new_listener.get());
+
+ return new_listener;
+}
+
+
+// Object event listeners (such as XmlHttpRequest and MessagePort) are
+// different from listeners on DOM nodes. An object event listener wrapper
+// only holds a weak reference to the JS function. A strong reference can
+// create a cycle.
+//
+// The lifetime of these objects is bounded by the life time of its JS
+// wrapper. So we can create a hidden reference from the JS wrapper to
+// to its JS function.
+//
+// (map)
+// XHR <---------- JS_wrapper
+// | (hidden) : ^
+// V V : (may reachable by closure)
+// V8_listener --------> JS_function
+// (weak) <-- may create a cycle if it is strong
+//
+// The persistent reference is made weak in the constructor
+// of V8ObjectEventListener.
+
+PassRefPtr<V8EventListener> V8Proxy::FindObjectEventListener(
+ v8::Local<v8::Value> listener, bool isInline)
+{
+ return FindEventListenerInList(m_xhr_listeners, listener, isInline);
+}
+
+
+PassRefPtr<V8EventListener> V8Proxy::FindOrCreateObjectEventListener(
+ v8::Local<v8::Value> obj, bool isInline)
+{
+ ASSERT(v8::Context::InContext());
+
+ if (!obj->IsObject())
+ return 0;
+
+ V8EventListener* wrapper =
+ FindEventListenerInList(m_xhr_listeners, obj, isInline);
+ if (wrapper)
+ return wrapper;
+
+ // Create a new one, and add to cache.
+ RefPtr<V8EventListener> new_listener =
+ V8ObjectEventListener::create(m_frame, v8::Local<v8::Object>::Cast(obj), isInline);
+ m_xhr_listeners.add(new_listener.get());
+
+ return new_listener.release();
+}
+
+
+static void RemoveEventListenerFromList(V8EventListenerList& list,
+ V8EventListener* listener)
+{
+ list.remove(listener);
+}
+
+
+void V8Proxy::RemoveV8EventListener(V8EventListener* listener)
+{
+ RemoveEventListenerFromList(m_event_listeners, listener);
+}
+
+
+void V8Proxy::RemoveObjectEventListener(V8ObjectEventListener* listener)
+{
+ RemoveEventListenerFromList(m_xhr_listeners, listener);
+}
+
+
+static void DisconnectEventListenersInList(V8EventListenerList& list)
+{
+ V8EventListenerList::iterator p = list.begin();
+ while (p != list.end()) {
+ (*p)->disconnectFrame();
+ ++p;
+ }
+ list.clear();
+}
+
+
+void V8Proxy::DisconnectEventListeners()
+{
+ DisconnectEventListenersInList(m_event_listeners);
+ DisconnectEventListenersInList(m_xhr_listeners);
+}
+
+
+v8::Handle<v8::Script> V8Proxy::CompileScript(v8::Handle<v8::String> code,
+ const String& fileName,
+ int baseLine)
+{
+ const uint16_t* fileNameString = FromWebCoreString(fileName);
+ v8::Handle<v8::String> name =
+ v8::String::New(fileNameString, fileName.length());
+ v8::Handle<v8::Integer> line = v8::Integer::New(baseLine);
+ v8::ScriptOrigin origin(name, line);
+ v8::Handle<v8::Script> script = v8::Script::Compile(code, &origin);
+ return script;
+}
+
+bool V8Proxy::HandleOutOfMemory()
+{
+ v8::Local<v8::Context> context = v8::Context::GetCurrent();
+
+ if (!context->HasOutOfMemoryException())
+ return false;
+
+ // Warning, error, disable JS for this frame?
+ Frame* frame = V8Proxy::retrieveFrame(context);
+
+ V8Proxy* proxy = V8Proxy::retrieve(frame);
+ // Clean m_context, and event handlers.
+ proxy->clearForClose();
+ // Destroy the global object.
+ proxy->DestroyGlobal();
+
+#if PLATFORM(CHROMIUM)
+ ChromiumBridge::notifyJSOutOfMemory(frame);
+#endif
+ // Disable JS.
+ Settings* settings = frame->settings();
+ ASSERT(settings);
+ settings->setJavaScriptEnabled(false);
+
+ return true;
+}
+
+void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources)
+{
+ InitContextIfNeeded();
+
+ v8::HandleScope handleScope;
+
+ // Set up the DOM window as the prototype of the new global object.
+ v8::Handle<v8::Context> windowContext = m_context;
+ v8::Handle<v8::Object> windowGlobal = windowContext->Global();
+ v8::Handle<v8::Value> windowWrapper =
+ V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, windowGlobal);
+
+ ASSERT(V8Proxy::DOMWrapperToNative<DOMWindow>(windowWrapper) ==
+ m_frame->domWindow());
+
+ v8::Persistent<v8::Context> context =
+ createNewContext(v8::Handle<v8::Object>());
+ v8::Context::Scope context_scope(context);
+ v8::Handle<v8::Object> global = context->Global();
+
+ v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
+ global->Set(implicitProtoString, windowWrapper);
+
+ // Give the code running in the new context a way to get access to the
+ // original context.
+ global->Set(v8::String::New("contentWindow"), windowGlobal);
+
+ // Run code in the new context.
+ for (size_t i = 0; i < sources.size(); ++i)
+ evaluate(sources[i], 0);
+
+ // Using the default security token means that the canAccess is always
+ // called, which is slow.
+ // TODO(aa): Use tokens where possible. This will mean keeping track of all
+ // created contexts so that they can all be updated when the document domain
+ // changes.
+ context->UseDefaultSecurityToken();
+ context.Dispose();
+}
+
+v8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* n)
+{
+ ASSERT(v8::Context::InContext());
+
+ // Compile the script.
+ v8::Local<v8::String> code = v8ExternalString(source.source());
+#if PLATFORM(CHROMIUM)
+ ChromiumBridge::traceEventBegin("v8.compile", n, "");
+#endif
+
+ // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
+ // 1, whereas v8 starts at 0.
+ v8::Handle<v8::Script> script = CompileScript(code, source.url(),
+ source.startLine() - 1);
+#if PLATFORM(CHROMIUM)
+ ChromiumBridge::traceEventEnd("v8.compile", n, "");
+ ChromiumBridge::traceEventBegin("v8.run", n, "");
+#endif
+
+ v8::Local<v8::Value> result;
+ {
+ // Isolate exceptions that occur when executing the code. These
+ // exceptions should not interfere with javascript code we might
+ // evaluate from C++ when returning from here
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+
+ // Set inlineCode to true for <a href="javascript:doSomething()">
+ // and false for <script>doSomething</script>. We make a rough guess at
+ // this based on whether the script source has a URL.
+ result = RunScript(script, source.url().string().isNull());
+ }
+#if PLATFORM(CHROMIUM)
+ ChromiumBridge::traceEventEnd("v8.run", n, "");
+#endif
+ return result;
+}
+
+v8::Local<v8::Value> V8Proxy::RunScript(v8::Handle<v8::Script> script,
+ bool inline_code)
+{
+ if (script.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ // Compute the source string and prevent against infinite recursion.
+ if (m_recursion >= kMaxRecursionDepth) {
+ v8::Local<v8::String> code =
+ v8ExternalString("throw RangeError('Recursion too deep')");
+ // TODO(kasperl): Ideally, we should be able to re-use the origin of the
+ // script passed to us as the argument instead of using an empty string
+ // and 0 baseLine.
+ script = CompileScript(code, "", 0);
+ }
+
+ if (HandleOutOfMemory())
+ ASSERT(script.IsEmpty());
+
+ if (script.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ // Save the previous value of the inlineCode flag and update the flag for
+ // the duration of the script invocation.
+ bool previous_inline_code = inlineCode();
+ setInlineCode(inline_code);
+
+ // Run the script and keep track of the current recursion depth.
+ v8::Local<v8::Value> result;
+ { ConsoleMessageScope scope;
+ m_recursion++;
+
+ // Evaluating the JavaScript could cause the frame to be deallocated,
+ // so we start the keep alive timer here.
+ // Frame::keepAlive method adds the ref count of the frame and sets a
+ // timer to decrease the ref count. It assumes that the current JavaScript
+ // execution finishs before firing the timer.
+ // See issue 1218756 and 914430.
+ m_frame->keepAlive();
+
+ result = script->Run();
+ m_recursion--;
+ }
+
+ if (HandleOutOfMemory())
+ ASSERT(result.IsEmpty());
+
+ // Handle V8 internal error situation (Out-of-memory).
+ if (result.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ // Restore inlineCode flag.
+ setInlineCode(previous_inline_code);
+
+ if (v8::V8::IsDead())
+ HandleFatalErrorInV8();
+
+ return result;
+}
+
+
+v8::Local<v8::Value> V8Proxy::CallFunction(v8::Handle<v8::Function> function,
+ v8::Handle<v8::Object> receiver,
+ int argc,
+ v8::Handle<v8::Value> args[])
+{
+ // For now, we don't put any artificial limitations on the depth
+ // of recursion that stems from calling functions. This is in
+ // contrast to the script evaluations.
+ v8::Local<v8::Value> result;
+ {
+ ConsoleMessageScope scope;
+
+ // Evaluating the JavaScript could cause the frame to be deallocated,
+ // so we start the keep alive timer here.
+ // Frame::keepAlive method adds the ref count of the frame and sets a
+ // timer to decrease the ref count. It assumes that the current JavaScript
+ // execution finishs before firing the timer.
+ // See issue 1218756 and 914430.
+ m_frame->keepAlive();
+
+ result = function->Call(receiver, argc, args);
+ }
+
+ if (v8::V8::IsDead())
+ HandleFatalErrorInV8();
+
+ return result;
+}
+
+
+v8::Local<v8::Function> V8Proxy::GetConstructor(V8ClassIndex::V8WrapperType t){
+ // A DOM constructor is a function instance created from a DOM constructor
+ // template. There is one instance per context. A DOM constructor is
+ // different from a normal function in two ways:
+ // 1) it cannot be called as constructor (aka, used to create a DOM object)
+ // 2) its __proto__ points to Object.prototype rather than
+ // Function.prototype.
+ // The reason for 2) is that, in Safari, a DOM constructor is a normal JS
+ // object, but not a function. Hotmail relies on the fact that, in Safari,
+ // HTMLElement.__proto__ == Object.prototype.
+ //
+ // m_object_prototype is a cache of the original Object.prototype.
+
+ ASSERT(ContextInitialized());
+ // Enter the context of the proxy to make sure that the
+ // function is constructed in the context corresponding to
+ // this proxy.
+ v8::Context::Scope scope(m_context);
+ v8::Handle<v8::FunctionTemplate> templ = GetTemplate(t);
+ // Getting the function might fail if we're running out of
+ // stack or memory.
+ v8::TryCatch try_catch;
+ v8::Local<v8::Function> value = templ->GetFunction();
+ if (value.IsEmpty())
+ return v8::Local<v8::Function>();
+ // Hotmail fix, see comments above.
+ value->Set(v8::String::New("__proto__"), m_object_prototype);
+ return value;
+}
+
+
+v8::Local<v8::Object> V8Proxy::CreateWrapperFromCache(V8ClassIndex::V8WrapperType type) {
+ int class_index = V8ClassIndex::ToInt(type);
+ v8::Local<v8::Value> cached_object =
+ m_wrapper_boilerplates->Get(v8::Integer::New(class_index));
+ if (cached_object->IsObject()) {
+ v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(cached_object);
+ return object->Clone();
+ }
+
+ // Not in cache.
+ InitContextIfNeeded();
+ v8::Context::Scope scope(m_context);
+ v8::Local<v8::Function> function = GetConstructor(type);
+ v8::Local<v8::Object> instance = SafeAllocation::NewInstance(function);
+ if (!instance.IsEmpty()) {
+ m_wrapper_boilerplates->Set(v8::Integer::New(class_index), instance);
+ return instance->Clone();
+ }
+ return v8::Local<v8::Object>();
+}
+
+
+// Get the string 'toString'.
+static v8::Persistent<v8::String> GetToStringName() {
+ static v8::Persistent<v8::String> value;
+ if (value.IsEmpty())
+ value = v8::Persistent<v8::String>::New(v8::String::New("toString"));
+ return value;
+}
+
+
+static v8::Handle<v8::Value> ConstructorToString(const v8::Arguments& args) {
+ // The DOM constructors' toString functions grab the current toString
+ // for Functions by taking the toString function of itself and then
+ // calling it with the constructor as its receiver. This means that
+ // changes to the Function prototype chain or toString function are
+ // reflected when printing DOM constructors. The only wart is that
+ // changes to a DOM constructor's toString's toString will cause the
+ // toString of the DOM constructor itself to change. This is extremely
+ // obscure and unlikely to be a problem.
+ v8::Handle<v8::Value> val = args.Callee()->Get(GetToStringName());
+ if (!val->IsFunction()) return v8::String::New("");
+ return v8::Handle<v8::Function>::Cast(val)->Call(args.This(), 0, NULL);
+}
+
+
+v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate(
+ V8ClassIndex::V8WrapperType type)
+{
+ v8::Persistent<v8::FunctionTemplate>* cache_cell =
+ V8ClassIndex::GetCache(type);
+ if (!(*cache_cell).IsEmpty())
+ return *cache_cell;
+
+ // not found
+ FunctionTemplateFactory factory = V8ClassIndex::GetFactory(type);
+ v8::Persistent<v8::FunctionTemplate> desc = factory();
+ // DOM constructors are functions and should print themselves as such.
+ // However, we will later replace their prototypes with Object
+ // prototypes so we need to explicitly override toString on the
+ // instance itself. If we later make DOM constructors full objects
+ // we can give them class names instead and Object.prototype.toString
+ // will work so we can remove this code.
+ static v8::Persistent<v8::FunctionTemplate> to_string_template;
+ if (to_string_template.IsEmpty()) {
+ to_string_template = v8::Persistent<v8::FunctionTemplate>::New(
+ v8::FunctionTemplate::New(ConstructorToString));
+ }
+ desc->Set(GetToStringName(), to_string_template);
+ switch (type) {
+ case V8ClassIndex::CSSSTYLEDECLARATION:
+ // The named property handler for style declarations has a
+ // setter. Therefore, the interceptor has to be on the object
+ // itself and not on the prototype object.
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(CSSStyleDeclaration),
+ USE_NAMED_PROPERTY_SETTER(CSSStyleDeclaration));
+ setCollectionStringOrNullIndexedGetter<CSSStyleDeclaration>(desc);
+ break;
+ case V8ClassIndex::CSSRULELIST:
+ setCollectionIndexedGetter<CSSRuleList, CSSRule>(desc,
+ V8ClassIndex::CSSRULE);
+ break;
+ case V8ClassIndex::CSSVALUELIST:
+ setCollectionIndexedGetter<CSSValueList, CSSValue>(
+ desc,
+ V8ClassIndex::CSSVALUE);
+ break;
+ case V8ClassIndex::CSSVARIABLESDECLARATION:
+ setCollectionStringOrNullIndexedGetter<CSSVariablesDeclaration>(desc);
+ break;
+ case V8ClassIndex::WEBKITCSSTRANSFORMVALUE:
+ setCollectionIndexedGetter<WebKitCSSTransformValue, CSSValue>(
+ desc,
+ V8ClassIndex::CSSVALUE);
+ break;
+ case V8ClassIndex::UNDETECTABLEHTMLCOLLECTION:
+ desc->InstanceTemplate()->MarkAsUndetectable(); // fall through
+ case V8ClassIndex::HTMLCOLLECTION:
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(HTMLCollection));
+ desc->InstanceTemplate()->SetCallAsFunctionHandler(
+ USE_CALLBACK(HTMLCollectionCallAsFunction));
+ setCollectionIndexedGetter<HTMLCollection, Node>(desc,
+ V8ClassIndex::NODE);
+ break;
+ case V8ClassIndex::HTMLOPTIONSCOLLECTION:
+ setCollectionNamedGetter<HTMLOptionsCollection, Node>(
+ desc,
+ V8ClassIndex::NODE);
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(
+ USE_INDEXED_PROPERTY_GETTER(HTMLOptionsCollection),
+ USE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection));
+ desc->InstanceTemplate()->SetCallAsFunctionHandler(
+ USE_CALLBACK(HTMLCollectionCallAsFunction));
+ break;
+ case V8ClassIndex::HTMLSELECTELEMENT:
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ nodeCollectionNamedPropertyGetter<HTMLSelectElement>,
+ 0,
+ 0,
+ 0,
+ 0,
+ v8::Integer::New(V8ClassIndex::NODE));
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(
+ nodeCollectionIndexedPropertyGetter<HTMLSelectElement>,
+ USE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection),
+ 0,
+ 0,
+ nodeCollectionIndexedPropertyEnumerator<HTMLSelectElement>,
+ v8::Integer::New(V8ClassIndex::NODE));
+ break;
+ case V8ClassIndex::HTMLDOCUMENT: {
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(HTMLDocument),
+ 0,
+ 0,
+ USE_NAMED_PROPERTY_DELETER(HTMLDocument));
+
+ // We add an extra internal field to all Document wrappers for
+ // storing a per document DOMImplementation wrapper.
+ //
+ // Additionally, we add two extra internal fields for
+ // HTMLDocuments to implement temporary shadowing of
+ // document.all. One field holds an object that is used as a
+ // marker. The other field holds the marker object if
+ // document.all is not shadowed and some other value if
+ // document.all is shadowed.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ ASSERT(instance_template->InternalFieldCount() ==
+ V8Custom::kDefaultWrapperInternalFieldCount);
+ instance_template->SetInternalFieldCount(
+ V8Custom::kHTMLDocumentInternalFieldCount);
+ break;
+ }
+#if ENABLE(SVG)
+ case V8ClassIndex::SVGDOCUMENT: // fall through
+#endif
+ case V8ClassIndex::DOCUMENT: {
+ // We add an extra internal field to all Document wrappers for
+ // storing a per document DOMImplementation wrapper.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ ASSERT(instance_template->InternalFieldCount() ==
+ V8Custom::kDefaultWrapperInternalFieldCount);
+ instance_template->SetInternalFieldCount(
+ V8Custom::kDocumentMinimumInternalFieldCount);
+ break;
+ }
+ case V8ClassIndex::HTMLAPPLETELEMENT: // fall through
+ case V8ClassIndex::HTMLEMBEDELEMENT: // fall through
+ case V8ClassIndex::HTMLOBJECTELEMENT:
+ // HTMLAppletElement, HTMLEmbedElement and HTMLObjectElement are
+ // inherited from HTMLPlugInElement, and they share the same property
+ // handling code.
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(HTMLPlugInElement),
+ USE_NAMED_PROPERTY_SETTER(HTMLPlugInElement));
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(
+ USE_INDEXED_PROPERTY_GETTER(HTMLPlugInElement),
+ USE_INDEXED_PROPERTY_SETTER(HTMLPlugInElement));
+ desc->InstanceTemplate()->SetCallAsFunctionHandler(
+ USE_CALLBACK(HTMLPlugInElement));
+ break;
+ case V8ClassIndex::HTMLFRAMESETELEMENT:
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(HTMLFrameSetElement));
+ break;
+ case V8ClassIndex::HTMLFORMELEMENT:
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(HTMLFormElement));
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(
+ USE_INDEXED_PROPERTY_GETTER(HTMLFormElement),
+ 0,
+ 0,
+ 0,
+ nodeCollectionIndexedPropertyEnumerator<HTMLFormElement>,
+ v8::Integer::New(V8ClassIndex::NODE));
+ break;
+ case V8ClassIndex::CANVASPIXELARRAY:
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(
+ USE_INDEXED_PROPERTY_GETTER(CanvasPixelArray),
+ USE_INDEXED_PROPERTY_SETTER(CanvasPixelArray));
+ break;
+ case V8ClassIndex::STYLESHEET: // fall through
+ case V8ClassIndex::CSSSTYLESHEET: {
+ // We add an extra internal field to hold a reference to
+ // the owner node.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ ASSERT(instance_template->InternalFieldCount() ==
+ V8Custom::kDefaultWrapperInternalFieldCount);
+ instance_template->SetInternalFieldCount(
+ V8Custom::kStyleSheetInternalFieldCount);
+ break;
+ }
+ case V8ClassIndex::MEDIALIST:
+ setCollectionStringOrNullIndexedGetter<MediaList>(desc);
+ break;
+ case V8ClassIndex::MIMETYPEARRAY:
+ setCollectionIndexedAndNamedGetters<MimeTypeArray, MimeType>(
+ desc,
+ V8ClassIndex::MIMETYPE);
+ break;
+ case V8ClassIndex::NAMEDNODEMAP:
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(NamedNodeMap));
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(
+ USE_INDEXED_PROPERTY_GETTER(NamedNodeMap),
+ 0,
+ 0,
+ 0,
+ collectionIndexedPropertyEnumerator<NamedNodeMap>,
+ v8::Integer::New(V8ClassIndex::NODE));
+ break;
+ case V8ClassIndex::NODELIST:
+ setCollectionIndexedGetter<NodeList, Node>(desc, V8ClassIndex::NODE);
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(NodeList));
+ break;
+ case V8ClassIndex::PLUGIN:
+ setCollectionIndexedAndNamedGetters<Plugin, MimeType>(
+ desc,
+ V8ClassIndex::MIMETYPE);
+ break;
+ case V8ClassIndex::PLUGINARRAY:
+ setCollectionIndexedAndNamedGetters<PluginArray, Plugin>(
+ desc,
+ V8ClassIndex::PLUGIN);
+ break;
+ case V8ClassIndex::STYLESHEETLIST:
+ desc->InstanceTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(StyleSheetList));
+ setCollectionIndexedGetter<StyleSheetList, StyleSheet>(
+ desc,
+ V8ClassIndex::STYLESHEET);
+ break;
+ case V8ClassIndex::DOMWINDOW: {
+ v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
+
+ desc->PrototypeTemplate()->SetNamedPropertyHandler(
+ USE_NAMED_PROPERTY_GETTER(DOMWindow));
+ desc->PrototypeTemplate()->SetIndexedPropertyHandler(
+ USE_INDEXED_PROPERTY_GETTER(DOMWindow));
+
+ desc->SetHiddenPrototype(true);
+
+ // Reserve spaces for references to location, history and
+ // navigator objects.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kDOMWindowInternalFieldCount);
+
+ // Set access check callbacks, but turned off initially.
+ // When a context is detached from a frame, turn on the access check.
+ // Turning on checks also invalidates inline caches of the object.
+ instance_template->SetAccessCheckCallbacks(
+ V8Custom::v8DOMWindowNamedSecurityCheck,
+ V8Custom::v8DOMWindowIndexedSecurityCheck,
+ v8::Integer::New(V8ClassIndex::DOMWINDOW),
+ false);
+ break;
+ }
+ case V8ClassIndex::LOCATION: {
+ // For security reasons, these functions are on the instance
+ // instead of on the prototype object to insure that they cannot
+ // be overwritten.
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ instance->SetAccessor(
+ v8::String::New("reload"),
+ V8Custom::v8LocationReloadAccessorGetter,
+ 0,
+ v8::Handle<v8::Value>(),
+ v8::ALL_CAN_READ,
+ static_cast<v8::PropertyAttribute>(v8::DontDelete|v8::ReadOnly));
+
+ instance->SetAccessor(
+ v8::String::New("replace"),
+ V8Custom::v8LocationReplaceAccessorGetter,
+ 0,
+ v8::Handle<v8::Value>(),
+ v8::ALL_CAN_READ,
+ static_cast<v8::PropertyAttribute>(v8::DontDelete|v8::ReadOnly));
+
+ instance->SetAccessor(
+ v8::String::New("assign"),
+ V8Custom::v8LocationAssignAccessorGetter,
+ 0,
+ v8::Handle<v8::Value>(),
+ v8::ALL_CAN_READ,
+ static_cast<v8::PropertyAttribute>(v8::DontDelete|v8::ReadOnly));
+ break;
+ }
+ case V8ClassIndex::HISTORY: {
+ break;
+ }
+
+ case V8ClassIndex::MESSAGECHANNEL: {
+ // Reserve two more internal fields for referencing the port1
+ // and port2 wrappers. This ensures that the port wrappers are
+ // kept alive when the channel wrapper is.
+ desc->SetCallHandler(USE_CALLBACK(MessageChannelConstructor));
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kMessageChannelInternalFieldCount);
+ break;
+ }
+
+ case V8ClassIndex::MESSAGEPORT: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kMessagePortInternalFieldCount);
+ break;
+ }
+
+#if ENABLE(WORKERS)
+ case V8ClassIndex::WORKER: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kWorkerInternalFieldCount);
+ desc->SetCallHandler(USE_CALLBACK(WorkerConstructor));
+ break;
+ }
+
+ case V8ClassIndex::WORKERCONTEXT: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kWorkerContextInternalFieldCount);
+ break;
+ }
+#endif // WORKERS
+
+
+ // The following objects are created from JavaScript.
+ case V8ClassIndex::DOMPARSER:
+ desc->SetCallHandler(USE_CALLBACK(DOMParserConstructor));
+ break;
+ case V8ClassIndex::WEBKITCSSMATRIX:
+ desc->SetCallHandler(USE_CALLBACK(WebKitCSSMatrixConstructor));
+ break;
+ case V8ClassIndex::WEBKITPOINT:
+ desc->SetCallHandler(USE_CALLBACK(WebKitPointConstructor));
+ break;
+ case V8ClassIndex::XMLSERIALIZER:
+ desc->SetCallHandler(USE_CALLBACK(XMLSerializerConstructor));
+ break;
+ case V8ClassIndex::XMLHTTPREQUEST: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kXMLHttpRequestInternalFieldCount);
+ desc->SetCallHandler(USE_CALLBACK(XMLHttpRequestConstructor));
+ break;
+ }
+ case V8ClassIndex::XMLHTTPREQUESTUPLOAD: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kXMLHttpRequestInternalFieldCount);
+ break;
+ }
+#if ENABLE(XPATH)
+ case V8ClassIndex::XPATHEVALUATOR:
+ desc->SetCallHandler(USE_CALLBACK(XPathEvaluatorConstructor));
+ break;
+#endif
+#if ENABLE(XSLT)
+ case V8ClassIndex::XSLTPROCESSOR:
+ desc->SetCallHandler(USE_CALLBACK(XSLTProcessorConstructor));
+ break;
+#endif
+ default:
+ break;
+ }
+
+ *cache_cell = desc;
+ return desc;
+}
+
+
+bool V8Proxy::ContextInitialized()
+{
+ // m_context, m_global, m_object_prototype and m_wrapper_boilerplates should
+ // all be non-empty if if m_context is non-empty.
+ ASSERT(m_context.IsEmpty() || !m_global.IsEmpty());
+ ASSERT(m_context.IsEmpty() || !m_object_prototype.IsEmpty());
+ ASSERT(m_context.IsEmpty() || !m_wrapper_boilerplates.IsEmpty());
+ return !m_context.IsEmpty();
+}
+
+
+DOMWindow* V8Proxy::retrieveWindow()
+{
+ // TODO: This seems very fragile. How do we know that the global object
+ // from the current context is something sensible? Do we need to use the
+ // last entered here? Who calls this?
+ return retrieveWindow(v8::Context::GetCurrent());
+}
+
+
+DOMWindow* V8Proxy::retrieveWindow(v8::Handle<v8::Context> context)
+{
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+ global = LookupDOMWrapper(V8ClassIndex::DOMWINDOW, global);
+ ASSERT(!global.IsEmpty());
+ return ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, global);
+}
+
+
+Frame* V8Proxy::retrieveFrame(v8::Handle<v8::Context> context)
+{
+ return retrieveWindow(context)->frame();
+}
+
+
+Frame* V8Proxy::retrieveActiveFrame()
+{
+ v8::Handle<v8::Context> context = v8::Context::GetEntered();
+ if (context.IsEmpty())
+ return 0;
+ return retrieveFrame(context);
+}
+
+
+Frame* V8Proxy::retrieveFrame()
+{
+ DOMWindow* window = retrieveWindow();
+ return window ? window->frame() : 0;
+}
+
+
+V8Proxy* V8Proxy::retrieve()
+{
+ DOMWindow* window = retrieveWindow();
+ ASSERT(window);
+ return retrieve(window->frame());
+}
+
+V8Proxy* V8Proxy::retrieve(Frame* frame)
+{
+ if (!frame)
+ return 0;
+ return frame->script()->isEnabled() ? frame->script()->proxy() : 0;
+}
+
+
+V8Proxy* V8Proxy::retrieve(ScriptExecutionContext* context)
+{
+ if (!context->isDocument())
+ return 0;
+ return retrieve(static_cast<Document*>(context)->frame());
+}
+
+
+void V8Proxy::disconnectFrame()
+{
+ // disconnect all event listeners
+ DisconnectEventListeners();
+}
+
+
+bool V8Proxy::isEnabled()
+{
+ Settings* settings = m_frame->settings();
+ if (!settings)
+ return false;
+
+ // In the common case, JavaScript is enabled and we're done.
+ if (settings->isJavaScriptEnabled())
+ return true;
+
+ // If JavaScript has been disabled, we need to look at the frame to tell
+ // whether this script came from the web or the embedder. Scripts from the
+ // embedder are safe to run, but scripts from the other sources are
+ // disallowed.
+ Document* document = m_frame->document();
+ if (!document)
+ return false;
+
+ SecurityOrigin* origin = document->securityOrigin();
+ if (origin->protocol().isEmpty())
+ return false; // Uninitialized document
+
+ if (origin->protocol() == "http" || origin->protocol() == "https")
+ return false; // Web site
+
+ // TODO(darin): the following are application decisions, and they should
+ // not be made at this layer. instead, we should bridge out to the
+ // embedder to allow them to override policy here.
+
+#if PLATFORM(CHROMIUM)
+ if (origin->protocol() == ChromiumBridge::uiResourceProtocol())
+ return true; // Embedder's scripts are ok to run
+#endif
+
+ // If the scheme is ftp: or file:, an empty file name indicates a directory
+ // listing, which requires JavaScript to function properly.
+ const char* kDirProtocols[] = { "ftp", "file" };
+#if PLATFORM(ANDROID)
+ // TODO(fqian): port arraysize function to Android.
+ for (size_t i = 0; i < 2; ++i) {
+#else
+ for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
+#endif
+ if (origin->protocol() == kDirProtocols[i]) {
+ const KURL& url = document->url();
+ return url.pathAfterLastSlash() == url.pathEnd();
+ }
+ }
+
+ return false; // Other protocols fall through to here
+}
+
+
+void V8Proxy::UpdateDocumentWrapper(v8::Handle<v8::Value> wrapper) {
+ ClearDocumentWrapper();
+
+ ASSERT(m_document.IsEmpty());
+ m_document = v8::Persistent<v8::Value>::New(wrapper);
+#ifndef NDEBUG
+ RegisterGlobalHandle(PROXY, this, m_document);
+#endif
+}
+
+
+void V8Proxy::ClearDocumentWrapper()
+{
+ if (!m_document.IsEmpty()) {
+#ifndef NDEBUG
+ UnregisterGlobalHandle(this, m_document);
+#endif
+ m_document.Dispose();
+ m_document.Clear();
+ }
+}
+
+
+void V8Proxy::DisposeContextHandles() {
+ if (!m_context.IsEmpty()) {
+ m_context.Dispose();
+ m_context.Clear();
+ }
+
+ if (!m_wrapper_boilerplates.IsEmpty()) {
+#ifndef NDEBUG
+ UnregisterGlobalHandle(this, m_wrapper_boilerplates);
+#endif
+ m_wrapper_boilerplates.Dispose();
+ m_wrapper_boilerplates.Clear();
+ }
+
+ if (!m_object_prototype.IsEmpty()) {
+#ifndef NDEBUG
+ UnregisterGlobalHandle(this, m_object_prototype);
+#endif
+ m_object_prototype.Dispose();
+ m_object_prototype.Clear();
+ }
+}
+
+void V8Proxy::clearForClose()
+{
+ if (!m_context.IsEmpty()) {
+ v8::HandleScope handle_scope;
+
+ ClearDocumentWrapper();
+ DisposeContextHandles();
+ }
+}
+
+
+void V8Proxy::clearForNavigation()
+{
+ if (!m_context.IsEmpty()) {
+ v8::HandleScope handle;
+ ClearDocumentWrapper();
+
+ v8::Context::Scope context_scope(m_context);
+
+ // Turn on access check on the old DOMWindow wrapper.
+ v8::Handle<v8::Object> wrapper =
+ LookupDOMWrapper(V8ClassIndex::DOMWINDOW, m_global);
+ ASSERT(!wrapper.IsEmpty());
+ wrapper->TurnOnAccessCheck();
+
+ // disconnect all event listeners
+ DisconnectEventListeners();
+
+ // Separate the context from its global object.
+ m_context->DetachGlobal();
+
+ DisposeContextHandles();
+
+ // Reinitialize the context so the global object points to
+ // the new DOM window.
+ InitContextIfNeeded();
+ }
+}
+
+
+void V8Proxy::SetSecurityToken() {
+ Document* document = m_frame->document();
+ // Setup security origin and security token
+ if (!document) {
+ m_context->UseDefaultSecurityToken();
+ return;
+ }
+
+ // Ask the document's SecurityOrigin to generate a security token.
+ // If two tokens are equal, then the SecurityOrigins canAccess each other.
+ // If two tokens are not equal, then we have to call canAccess.
+ // Note: we can't use the HTTPOrigin if it was set from the DOM.
+ SecurityOrigin* origin = document->securityOrigin();
+ String token;
+ if (!origin->domainWasSetInDOM())
+ token = document->securityOrigin()->toString();
+
+ // An empty or "null" token means we always have to call
+ // canAccess. The toString method on securityOrigins returns the
+ // string "null" for empty security origins and for security
+ // origins that should only allow access to themselves. In this
+ // case, we use the global object as the security token to avoid
+ // calling canAccess when a script accesses its own objects.
+ if (token.isEmpty() || token == "null") {
+ m_context->UseDefaultSecurityToken();
+ return;
+ }
+
+ CString utf8_token = token.utf8();
+ // NOTE: V8 does identity comparison in fast path, must use a symbol
+ // as the security token.
+ m_context->SetSecurityToken(
+ v8::String::NewSymbol(utf8_token.data(), utf8_token.length()));
+}
+
+
+void V8Proxy::updateDocument()
+{
+ if (!m_frame->document())
+ return;
+
+ if (m_global.IsEmpty()) {
+ ASSERT(m_context.IsEmpty());
+ return;
+ }
+
+ {
+ v8::HandleScope scope;
+ SetSecurityToken();
+ }
+}
+
+void V8Proxy::updateSecurityOrigin()
+{
+ v8::HandleScope scope;
+ SetSecurityToken();
+}
+
+// Same origin policy implementation:
+//
+// Same origin policy prevents JS code from domain A access JS & DOM objects
+// in a different domain B. There are exceptions and several objects are
+// accessible by cross-domain code. For example, the window.frames object is
+// accessible by code from a different domain, but window.document is not.
+//
+// The binding code sets security check callbacks on a function template,
+// and accessing instances of the template calls the callback function.
+// The callback function checks same origin policy.
+//
+// Callback functions are expensive. V8 uses a security token string to do
+// fast access checks for the common case where source and target are in the
+// same domain. A security token is a string object that represents
+// the protocol/url/port of a domain.
+//
+// There are special cases where a security token matching is not enough.
+// For example, JavaScript can set its domain to a super domain by calling
+// document.setDomain(...). In these cases, the binding code can reset
+// a context's security token to its global object so that the fast access
+// check will always fail.
+
+// Check if the current execution context can access a target frame.
+// First it checks same domain policy using the lexical context
+//
+// This is equivalent to KJS::Window::allowsAccessFrom(ExecState*, String&).
+bool V8Proxy::CanAccessPrivate(DOMWindow* target_window)
+{
+ ASSERT(target_window);
+
+ String message;
+
+ DOMWindow* origin_window = retrieveWindow();
+ if (origin_window == target_window)
+ return true;
+
+ if (!origin_window)
+ return false;
+
+ // JS may be attempting to access the "window" object, which should be
+ // valid, even if the document hasn't been constructed yet.
+ // If the document doesn't exist yet allow JS to access the window object.
+ if (!origin_window->document())
+ return true;
+
+ const SecurityOrigin* active_security_origin = origin_window->securityOrigin();
+ const SecurityOrigin* target_security_origin = target_window->securityOrigin();
+
+ // We have seen crashes were the security origin of the target has not been
+ // initialized. Defend against that.
+ ASSERT(target_security_origin);
+ if (!target_security_origin)
+ return false;
+
+ if (active_security_origin->canAccess(target_security_origin))
+ return true;
+
+ // Allow access to a "about:blank" page if the dynamic context is a
+ // detached context of the same frame as the blank page.
+ if (target_security_origin->isEmpty() &&
+ origin_window->frame() == target_window->frame())
+ return true;
+
+ return false;
+}
+
+
+bool V8Proxy::CanAccessFrame(Frame* target, bool report_error)
+{
+ // The subject is detached from a frame, deny accesses.
+ if (!target)
+ return false;
+
+ if (!CanAccessPrivate(target->domWindow())) {
+ if (report_error)
+ ReportUnsafeAccessTo(target, REPORT_NOW);
+ return false;
+ }
+ return true;
+}
+
+
+bool V8Proxy::CheckNodeSecurity(Node* node)
+{
+ if (!node)
+ return false;
+
+ Frame* target = node->document()->frame();
+
+ if (!target)
+ return false;
+
+ return CanAccessFrame(target, true);
+}
+
+v8::Persistent<v8::Context> V8Proxy::createNewContext(
+ v8::Handle<v8::Object> global)
+{
+ v8::Persistent<v8::Context> result;
+
+ // Create a new environment using an empty template for the shadow
+ // object. Reuse the global object if one has been created earlier.
+ v8::Persistent<v8::ObjectTemplate> globalTemplate =
+ V8DOMWindow::GetShadowObjectTemplate();
+ if (globalTemplate.IsEmpty())
+ return result;
+
+ // Install a security handler with V8.
+ globalTemplate->SetAccessCheckCallbacks(
+ V8Custom::v8DOMWindowNamedSecurityCheck,
+ V8Custom::v8DOMWindowIndexedSecurityCheck,
+ v8::Integer::New(V8ClassIndex::DOMWINDOW));
+
+ // Dynamically tell v8 about our extensions now.
+ const char** extensionNames = new const char*[m_extensions.size()];
+ int index = 0;
+ for (V8ExtensionList::iterator it = m_extensions.begin();
+ it != m_extensions.end(); ++it) {
+ if (it->scheme.length() > 0 &&
+ it->scheme != m_frame->document()->url().protocol())
+ continue;
+
+ extensionNames[index++] = it->extension->name();
+ }
+ v8::ExtensionConfiguration extensions(index, extensionNames);
+ result = v8::Context::New(&extensions, globalTemplate, global);
+ delete [] extensionNames;
+ extensionNames = 0;
+
+ return result;
+}
+
+// Create a new environment and setup the global object.
+//
+// The global object corresponds to a DOMWindow instance. However, to
+// allow properties of the JS DOMWindow instance to be shadowed, we
+// use a shadow object as the global object and use the JS DOMWindow
+// instance as the prototype for that shadow object. The JS DOMWindow
+// instance is undetectable from javascript code because the __proto__
+// accessors skip that object.
+//
+// The shadow object and the DOMWindow instance are seen as one object
+// from javascript. The javascript object that corresponds to a
+// DOMWindow instance is the shadow object. When mapping a DOMWindow
+// instance to a V8 object, we return the shadow object.
+//
+// To implement split-window, see
+// 1) https://bugs.webkit.org/show_bug.cgi?id=17249
+// 2) https://wiki.mozilla.org/Gecko:SplitWindow
+// 3) https://bugzilla.mozilla.org/show_bug.cgi?id=296639
+// we need to split the shadow object further into two objects:
+// an outer window and an inner window. The inner window is the hidden
+// prototype of the outer window. The inner window is the default
+// global object of the context. A variable declared in the global
+// scope is a property of the inner window.
+//
+// The outer window sticks to a Frame, it is exposed to JavaScript
+// via window.window, window.self, window.parent, etc. The outer window
+// has a security token which is the domain. The outer window cannot
+// have its own properties. window.foo = 'x' is delegated to the
+// inner window.
+//
+// When a frame navigates to a new page, the inner window is cut off
+// the outer window, and the outer window identify is preserved for
+// the frame. However, a new inner window is created for the new page.
+// If there are JS code holds a closure to the old inner window,
+// it won't be able to reach the outer window via its global object.
+void V8Proxy::InitContextIfNeeded()
+{
+ // Bail out if the context has already been initialized.
+ if (!m_context.IsEmpty())
+ return;
+
+ // Create a handle scope for all local handles.
+ v8::HandleScope handle_scope;
+
+ // Setup the security handlers and message listener. This only has
+ // to be done once.
+ static bool v8_initialized = false;
+ if (!v8_initialized) {
+ // Tells V8 not to call the default OOM handler, binding code
+ // will handle it.
+ v8::V8::IgnoreOutOfMemoryException();
+ v8::V8::SetFatalErrorHandler(ReportFatalErrorInV8);
+
+ v8::V8::SetGlobalGCPrologueCallback(&GCPrologue);
+ v8::V8::SetGlobalGCEpilogueCallback(&GCEpilogue);
+
+ v8::V8::AddMessageListener(HandleConsoleMessage);
+
+ v8::V8::SetFailedAccessCheckCallbackFunction(ReportUnsafeJavaScriptAccess);
+
+ v8_initialized = true;
+ }
+
+ m_context = createNewContext(m_global);
+ if (m_context.IsEmpty())
+ return;
+
+ // Starting from now, use local context only.
+ v8::Local<v8::Context> context = GetContext();
+ v8::Context::Scope context_scope(context);
+
+ // Store the first global object created so we can reuse it.
+ if (m_global.IsEmpty()) {
+ m_global = v8::Persistent<v8::Object>::New(context->Global());
+ // Bail out if allocation of the first global objects fails.
+ if (m_global.IsEmpty()) {
+ DisposeContextHandles();
+ return;
+ }
+#ifndef NDEBUG
+ RegisterGlobalHandle(PROXY, this, m_global);
+#endif
+ }
+
+ // Allocate strings used during initialization.
+ v8::Handle<v8::String> object_string = v8::String::New("Object");
+ v8::Handle<v8::String> prototype_string = v8::String::New("prototype");
+ v8::Handle<v8::String> implicit_proto_string = v8::String::New("__proto__");
+ // Bail out if allocation failed.
+ if (object_string.IsEmpty() ||
+ prototype_string.IsEmpty() ||
+ implicit_proto_string.IsEmpty()) {
+ DisposeContextHandles();
+ return;
+ }
+
+ // Allocate clone cache and pre-allocated objects
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(
+ m_global->Get(object_string));
+ m_object_prototype = v8::Persistent<v8::Value>::New(
+ object->Get(prototype_string));
+ m_wrapper_boilerplates = v8::Persistent<v8::Array>::New(
+ v8::Array::New(V8ClassIndex::WRAPPER_TYPE_COUNT));
+ // Bail out if allocation failed.
+ if (m_object_prototype.IsEmpty()) {
+ DisposeContextHandles();
+ return;
+ }
+#ifndef NDEBUG
+ RegisterGlobalHandle(PROXY, this, m_object_prototype);
+ RegisterGlobalHandle(PROXY, this, m_wrapper_boilerplates);
+#endif
+
+ // Create a new JS window object and use it as the prototype for the
+ // shadow global object.
+ v8::Handle<v8::Function> window_constructor =
+ GetConstructor(V8ClassIndex::DOMWINDOW);
+ v8::Local<v8::Object> js_window =
+ SafeAllocation::NewInstance(window_constructor);
+ // Bail out if allocation failed.
+ if (js_window.IsEmpty()) {
+ DisposeContextHandles();
+ return;
+ }
+
+ DOMWindow* window = m_frame->domWindow();
+
+ // Wrap the window.
+ SetDOMWrapper(js_window,
+ V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW),
+ window);
+
+ window->ref();
+ V8Proxy::SetJSWrapperForDOMObject(window,
+ v8::Persistent<v8::Object>::New(js_window));
+
+ // Insert the window instance as the prototype of the shadow object.
+ v8::Handle<v8::Object> v8_global = context->Global();
+ v8_global->Set(implicit_proto_string, js_window);
+
+ SetSecurityToken();
+
+ m_frame->loader()->dispatchWindowObjectAvailable();
+}
+
+
+void V8Proxy::SetDOMException(int exception_code)
+{
+ if (exception_code <= 0)
+ return;
+
+ ExceptionCodeDescription description;
+ getExceptionCodeDescription(exception_code, description);
+
+ v8::Handle<v8::Value> exception;
+ switch (description.type) {
+ case DOMExceptionType:
+ exception = ToV8Object(V8ClassIndex::DOMCOREEXCEPTION,
+ DOMCoreException::create(description));
+ break;
+ case RangeExceptionType:
+ exception = ToV8Object(V8ClassIndex::RANGEEXCEPTION,
+ RangeException::create(description));
+ break;
+ case EventExceptionType:
+ exception = ToV8Object(V8ClassIndex::EVENTEXCEPTION,
+ EventException::create(description));
+ break;
+ case XMLHttpRequestExceptionType:
+ exception = ToV8Object(V8ClassIndex::XMLHTTPREQUESTEXCEPTION,
+ XMLHttpRequestException::create(description));
+ break;
+#if ENABLE(SVG)
+ case SVGExceptionType:
+ exception = ToV8Object(V8ClassIndex::SVGEXCEPTION,
+ SVGException::create(description));
+ break;
+#endif
+#if ENABLE(XPATH)
+ case XPathExceptionType:
+ exception = ToV8Object(V8ClassIndex::XPATHEXCEPTION,
+ XPathException::create(description));
+ break;
+#endif
+ }
+
+ ASSERT(!exception.IsEmpty());
+ v8::ThrowException(exception);
+}
+
+v8::Handle<v8::Value> V8Proxy::ThrowError(ErrorType type, const char* message)
+{
+ switch (type) {
+ case RANGE_ERROR:
+ return v8::ThrowException(v8::Exception::RangeError(v8String(message)));
+ case REFERENCE_ERROR:
+ return v8::ThrowException(
+ v8::Exception::ReferenceError(v8String(message)));
+ case SYNTAX_ERROR:
+ return v8::ThrowException(v8::Exception::SyntaxError(v8String(message)));
+ case TYPE_ERROR:
+ return v8::ThrowException(v8::Exception::TypeError(v8String(message)));
+ case GENERAL_ERROR:
+ return v8::ThrowException(v8::Exception::Error(v8String(message)));
+ default:
+ ASSERT(false);
+ return v8::Handle<v8::Value>();
+ }
+}
+
+v8::Local<v8::Context> V8Proxy::GetContext(Frame* frame)
+{
+ V8Proxy* proxy = retrieve(frame);
+ if (!proxy)
+ return v8::Local<v8::Context>();
+
+ proxy->InitContextIfNeeded();
+ return proxy->GetContext();
+}
+
+v8::Local<v8::Context> V8Proxy::GetCurrentContext()
+{
+ return v8::Context::GetCurrent();
+}
+
+v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type, void* imp)
+{
+ ASSERT(type != V8ClassIndex::EVENTLISTENER);
+ ASSERT(type != V8ClassIndex::EVENTTARGET);
+ ASSERT(type != V8ClassIndex::EVENT);
+
+ bool is_active_dom_object = false;
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE:
+ DOM_NODE_TYPES(MAKE_CASE)
+#if ENABLE(SVG)
+ SVG_NODE_TYPES(MAKE_CASE)
+#endif
+ return NodeToV8Object(static_cast<Node*>(imp));
+ case V8ClassIndex::CSSVALUE:
+ return CSSValueToV8Object(static_cast<CSSValue*>(imp));
+ case V8ClassIndex::CSSRULE:
+ return CSSRuleToV8Object(static_cast<CSSRule*>(imp));
+ case V8ClassIndex::STYLESHEET:
+ return StyleSheetToV8Object(static_cast<StyleSheet*>(imp));
+ case V8ClassIndex::DOMWINDOW:
+ return WindowToV8Object(static_cast<DOMWindow*>(imp));
+#if ENABLE(SVG)
+ SVG_NONNODE_TYPES(MAKE_CASE)
+ if (type == V8ClassIndex::SVGELEMENTINSTANCE)
+ return SVGElementInstanceToV8Object(static_cast<SVGElementInstance*>(imp));
+ return SVGObjectWithContextToV8Object(type, imp);
+#endif
+
+ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ is_active_dom_object = true;
+ break;
+ default:
+ break;
+ }
+
+#undef MAKE_CASE
+
+ if (!imp) return v8::Null();
+
+ // Non DOM node
+ v8::Persistent<v8::Object> result = is_active_dom_object ?
+ getActiveDOMObjectMap().get(imp) :
+ getDOMObjectMap().get(imp);
+ if (result.IsEmpty()) {
+ v8::Local<v8::Object> v8obj = InstantiateV8Object(type, type, imp);
+ if (!v8obj.IsEmpty()) {
+ // Go through big switch statement, it has some duplications
+ // that were handled by code above (such as CSSVALUE, CSSRULE, etc).
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: static_cast<NAME*>(imp)->ref(); break;
+ DOM_OBJECT_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default:
+ ASSERT(false);
+ }
+ result = v8::Persistent<v8::Object>::New(v8obj);
+ if (is_active_dom_object)
+ SetJSWrapperForActiveDOMObject(imp, result);
+ else
+ SetJSWrapperForDOMObject(imp, result);
+
+ // Special case for non-node objects History, Location and
+ // Navigator. Both Safari and FF let Location and Navigator JS
+ // wrappers survive GC. To mimic their behaviors, V8 creates
+ // hidden references from the DOMWindow to these wrapper
+ // objects. These references get cleared when the DOMWindow is
+ // reused by a new page.
+ switch (type) {
+ case V8ClassIndex::HISTORY:
+ SetHiddenWindowReference(static_cast<History*>(imp)->frame(),
+ V8Custom::kDOMWindowHistoryIndex, result);
+ break;
+ case V8ClassIndex::NAVIGATOR:
+ SetHiddenWindowReference(static_cast<Navigator*>(imp)->frame(),
+ V8Custom::kDOMWindowNavigatorIndex, result);
+ break;
+ case V8ClassIndex::LOCATION:
+ SetHiddenWindowReference(static_cast<Location*>(imp)->frame(),
+ V8Custom::kDOMWindowLocationIndex, result);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+
+void V8Proxy::SetHiddenWindowReference(Frame* frame,
+ const int internal_index,
+ v8::Handle<v8::Object> jsobj)
+{
+ // Get DOMWindow
+ if (!frame) return; // Object might be detached from window
+ v8::Handle<v8::Context> context = GetContext(frame);
+ if (context.IsEmpty()) return;
+
+ ASSERT(internal_index < V8Custom::kDOMWindowInternalFieldCount);
+
+ v8::Handle<v8::Object> global = context->Global();
+ // Look for real DOM wrapper.
+ global = LookupDOMWrapper(V8ClassIndex::DOMWINDOW, global);
+ ASSERT(!global.IsEmpty());
+ ASSERT(global->GetInternalField(internal_index)->IsUndefined());
+ global->SetInternalField(internal_index, jsobj);
+}
+
+
+V8ClassIndex::V8WrapperType V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object> object)
+{
+ ASSERT(MaybeDOMWrapper(object));
+ v8::Handle<v8::Value> type =
+ object->GetInternalField(V8Custom::kDOMWrapperTypeIndex);
+ return V8ClassIndex::FromInt(type->Int32Value());
+}
+
+
+void* V8Proxy::ToNativeObjectImpl(V8ClassIndex::V8WrapperType type,
+ v8::Handle<v8::Value> object)
+{
+ // Native event listener is per frame, it cannot be handled
+ // by this generic function.
+ ASSERT(type != V8ClassIndex::EVENTLISTENER);
+ ASSERT(type != V8ClassIndex::EVENTTARGET);
+
+ ASSERT(MaybeDOMWrapper(object));
+
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE:
+ DOM_NODE_TYPES(MAKE_CASE)
+#if ENABLE(SVG)
+ SVG_NODE_TYPES(MAKE_CASE)
+#endif
+ ASSERT(false);
+ return NULL;
+ case V8ClassIndex::XMLHTTPREQUEST:
+ return DOMWrapperToNative<XMLHttpRequest>(object);
+ case V8ClassIndex::EVENT:
+ return DOMWrapperToNative<Event>(object);
+ case V8ClassIndex::CSSRULE:
+ return DOMWrapperToNative<CSSRule>(object);
+ default:
+ break;
+ }
+#undef MAKE_CASE
+
+ return DOMWrapperToNative<void>(object);
+}
+
+v8::Handle<v8::Object> V8Proxy::LookupDOMWrapper(
+ V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> value)
+{
+ if (value.IsEmpty())
+ return v8::Handle<v8::Object>();
+
+ v8::Handle<v8::FunctionTemplate> desc = V8Proxy::GetTemplate(type);
+ while (value->IsObject()) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
+ if (desc->HasInstance(object))
+ return object;
+
+ value = object->GetPrototype();
+ }
+ return v8::Handle<v8::Object>();
+}
+
+
+PassRefPtr<NodeFilter> V8Proxy::ToNativeNodeFilter(v8::Handle<v8::Value> filter)
+{
+ // A NodeFilter is used when walking through a DOM tree or iterating tree
+ // nodes.
+ // TODO: we may want to cache NodeFilterCondition and NodeFilter
+ // object, but it is minor.
+ // NodeFilter is passed to NodeIterator that has a ref counted pointer
+ // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterCondition.
+ // In NodeFilterCondition, filter object is persisted in its constructor,
+ // and disposed in its destructor.
+ if (!filter->IsFunction())
+ return 0;
+
+ NodeFilterCondition* cond = new V8NodeFilterCondition(filter);
+ return NodeFilter::create(cond);
+}
+
+
+v8::Local<v8::Object> V8Proxy::InstantiateV8Object(
+ V8ClassIndex::V8WrapperType desc_type,
+ V8ClassIndex::V8WrapperType cptr_type,
+ void* imp)
+{
+ // Make a special case for document.all
+ if (desc_type == V8ClassIndex::HTMLCOLLECTION &&
+ static_cast<HTMLCollection*>(imp)->type() == HTMLCollection::DocAll) {
+ desc_type = V8ClassIndex::UNDETECTABLEHTMLCOLLECTION;
+ }
+
+ V8Proxy* proxy = V8Proxy::retrieve();
+ v8::Local<v8::Object> instance;
+ if (proxy) {
+ instance = proxy->CreateWrapperFromCache(desc_type);
+ } else {
+ v8::Local<v8::Function> function = GetTemplate(desc_type)->GetFunction();
+ instance = SafeAllocation::NewInstance(function);
+ }
+ if (!instance.IsEmpty()) {
+ // Avoid setting the DOM wrapper for failed allocations.
+ SetDOMWrapper(instance, V8ClassIndex::ToInt(cptr_type), imp);
+ }
+ return instance;
+}
+
+v8::Handle<v8::Value> V8Proxy::CheckNewLegal(const v8::Arguments& args)
+{
+ if (!AllowAllocation::m_current)
+ return ThrowError(TYPE_ERROR, "Illegal constructor");
+
+ return args.This();
+}
+
+void V8Proxy::SetDOMWrapper(v8::Handle<v8::Object> obj, int type, void* cptr)
+{
+ ASSERT(obj->InternalFieldCount() >= 2);
+ obj->SetInternalField(V8Custom::kDOMWrapperObjectIndex, WrapCPointer(cptr));
+ obj->SetInternalField(V8Custom::kDOMWrapperTypeIndex, v8::Integer::New(type));
+}
+
+
+#ifndef NDEBUG
+bool V8Proxy::MaybeDOMWrapper(v8::Handle<v8::Value> value)
+{
+ if (value.IsEmpty() || !value->IsObject()) return false;
+
+ v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(value);
+ if (obj->InternalFieldCount() == 0) return false;
+
+ ASSERT(obj->InternalFieldCount() >=
+ V8Custom::kDefaultWrapperInternalFieldCount);
+
+ v8::Handle<v8::Value> type =
+ obj->GetInternalField(V8Custom::kDOMWrapperTypeIndex);
+ ASSERT(type->IsInt32());
+ ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() &&
+ type->Int32Value() < V8ClassIndex::CLASSINDEX_END);
+
+ v8::Handle<v8::Value> wrapper =
+ obj->GetInternalField(V8Custom::kDOMWrapperObjectIndex);
+ ASSERT(wrapper->IsNumber() || wrapper->IsExternal());
+
+ return true;
+}
+#endif
+
+
+bool V8Proxy::IsDOMEventWrapper(v8::Handle<v8::Value> value)
+{
+ // All kinds of events use EVENT as dom type in JS wrappers.
+ // See EventToV8Object
+ return IsWrapperOfType(value, V8ClassIndex::EVENT);
+}
+
+bool V8Proxy::IsWrapperOfType(v8::Handle<v8::Value> value,
+ V8ClassIndex::V8WrapperType classType)
+{
+ if (value.IsEmpty() || !value->IsObject()) return false;
+
+ v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(value);
+ if (obj->InternalFieldCount() == 0) return false;
+
+ ASSERT(obj->InternalFieldCount() >=
+ V8Custom::kDefaultWrapperInternalFieldCount);
+
+ v8::Handle<v8::Value> wrapper =
+ obj->GetInternalField(V8Custom::kDOMWrapperObjectIndex);
+ ASSERT(wrapper->IsNumber() || wrapper->IsExternal());
+
+ v8::Handle<v8::Value> type =
+ obj->GetInternalField(V8Custom::kDOMWrapperTypeIndex);
+ ASSERT(type->IsInt32());
+ ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() &&
+ type->Int32Value() < V8ClassIndex::CLASSINDEX_END);
+
+ return V8ClassIndex::FromInt(type->Int32Value()) == classType;
+}
+
+#if ENABLE(VIDEO)
+#define FOR_EACH_VIDEO_TAG(macro) \
+ macro(audio, AUDIO) \
+ macro(source, SOURCE) \
+ macro(video, VIDEO)
+#else
+#define FOR_EACH_VIDEO_TAG(macro)
+#endif
+
+#define FOR_EACH_TAG(macro) \
+ macro(a, ANCHOR) \
+ macro(applet, APPLET) \
+ macro(area, AREA) \
+ macro(base, BASE) \
+ macro(basefont, BASEFONT) \
+ macro(blockquote, BLOCKQUOTE) \
+ macro(body, BODY) \
+ macro(br, BR) \
+ macro(button, BUTTON) \
+ macro(caption, TABLECAPTION) \
+ macro(col, TABLECOL) \
+ macro(colgroup, TABLECOL) \
+ macro(del, MOD) \
+ macro(canvas, CANVAS) \
+ macro(dir, DIRECTORY) \
+ macro(div, DIV) \
+ macro(dl, DLIST) \
+ macro(embed, EMBED) \
+ macro(fieldset, FIELDSET) \
+ macro(font, FONT) \
+ macro(form, FORM) \
+ macro(frame, FRAME) \
+ macro(frameset, FRAMESET) \
+ macro(h1, HEADING) \
+ macro(h2, HEADING) \
+ macro(h3, HEADING) \
+ macro(h4, HEADING) \
+ macro(h5, HEADING) \
+ macro(h6, HEADING) \
+ macro(head, HEAD) \
+ macro(hr, HR) \
+ macro(html, HTML) \
+ macro(img, IMAGE) \
+ macro(iframe, IFRAME) \
+ macro(image, IMAGE) \
+ macro(input, INPUT) \
+ macro(ins, MOD) \
+ macro(isindex, ISINDEX) \
+ macro(keygen, SELECT) \
+ macro(label, LABEL) \
+ macro(legend, LEGEND) \
+ macro(li, LI) \
+ macro(link, LINK) \
+ macro(listing, PRE) \
+ macro(map, MAP) \
+ macro(marquee, MARQUEE) \
+ macro(menu, MENU) \
+ macro(meta, META) \
+ macro(object, OBJECT) \
+ macro(ol, OLIST) \
+ macro(optgroup, OPTGROUP) \
+ macro(option, OPTION) \
+ macro(p, PARAGRAPH) \
+ macro(param, PARAM) \
+ macro(pre, PRE) \
+ macro(q, QUOTE) \
+ macro(script, SCRIPT) \
+ macro(select, SELECT) \
+ macro(style, STYLE) \
+ macro(table, TABLE) \
+ macro(thead, TABLESECTION) \
+ macro(tbody, TABLESECTION) \
+ macro(tfoot, TABLESECTION) \
+ macro(td, TABLECELL) \
+ macro(th, TABLECELL) \
+ macro(tr, TABLEROW) \
+ macro(textarea, TEXTAREA) \
+ macro(title, TITLE) \
+ macro(ul, ULIST) \
+ macro(xmp, PRE)
+
+V8ClassIndex::V8WrapperType V8Proxy::GetHTMLElementType(HTMLElement* element)
+{
+ static HashMap<String, V8ClassIndex::V8WrapperType> map;
+ if (map.isEmpty()) {
+#define ADD_TO_HASH_MAP(tag, name) \
+ map.set(#tag, V8ClassIndex::HTML##name##ELEMENT);
+FOR_EACH_TAG(ADD_TO_HASH_MAP)
+#if ENABLE(VIDEO)
+ if (MediaPlayer::isAvailable()) {
+FOR_EACH_VIDEO_TAG(ADD_TO_HASH_MAP)
+ }
+#endif
+#undef ADD_TO_HASH_MAP
+ }
+
+ V8ClassIndex::V8WrapperType t = map.get(element->localName().impl());
+ if (t == 0)
+ return V8ClassIndex::HTMLELEMENT;
+ return t;
+}
+#undef FOR_EACH_TAG
+
+#if ENABLE(SVG)
+
+#if ENABLE(SVG_ANIMATION)
+#define FOR_EACH_ANIMATION_TAG(macro) \
+ macro(animateColor, ANIMATECOLOR) \
+ macro(animate, ANIMATE) \
+ macro(animateTransform, ANIMATETRANSFORM) \
+ macro(set, SET)
+#else
+#define FOR_EACH_ANIMATION_TAG(macro)
+#endif
+
+#if ENABLE(SVG_FILTERS)
+#define FOR_EACH_FILTERS_TAG(macro) \
+ macro(feBlend, FEBLEND) \
+ macro(feColorMatrix, FECOLORMATRIX) \
+ macro(feComponentTransfer, FECOMPONENTTRANSFER) \
+ macro(feComposite, FECOMPOSITE) \
+ macro(feDiffuseLighting, FEDIFFUSELIGHTING) \
+ macro(feDisplacementMap, FEDISPLACEMENTMAP) \
+ macro(feDistantLight, FEDISTANTLIGHT) \
+ macro(feFlood, FEFLOOD) \
+ macro(feFuncA, FEFUNCA) \
+ macro(feFuncB, FEFUNCB) \
+ macro(feFuncG, FEFUNCG) \
+ macro(feFuncR, FEFUNCR) \
+ macro(feGaussianBlur, FEGAUSSIANBLUR) \
+ macro(feImage, FEIMAGE) \
+ macro(feMerge, FEMERGE) \
+ macro(feMergeNode, FEMERGENODE) \
+ macro(feOffset, FEOFFSET) \
+ macro(fePointLight, FEPOINTLIGHT) \
+ macro(feSpecularLighting, FESPECULARLIGHTING) \
+ macro(feSpotLight, FESPOTLIGHT) \
+ macro(feTile, FETILE) \
+ macro(feTurbulence, FETURBULENCE) \
+ macro(filter, FILTER)
+#else
+#define FOR_EACH_FILTERS_TAG(macro)
+#endif
+
+#if ENABLE(SVG_FONTS)
+#define FOR_EACH_FONTS_TAG(macro) \
+ macro(definition-src, DEFINITIONSRC) \
+ macro(font-face, FONTFACE) \
+ macro(font-face-format, FONTFACEFORMAT) \
+ macro(font-face-name, FONTFACENAME) \
+ macro(font-face-src, FONTFACESRC) \
+ macro(font-face-uri, FONTFACEURI)
+#else
+#define FOR_EACH_FONTS_TAG(marco)
+#endif
+
+#if ENABLE(SVG_FOREIGN_OBJECT)
+#define FOR_EACH_FOREIGN_OBJECT_TAG(macro) \
+ macro(foreignObject, FOREIGNOBJECT)
+#else
+#define FOR_EACH_FOREIGN_OBJECT_TAG(macro)
+#endif
+
+#if ENABLE(SVG_USE)
+#define FOR_EACH_USE_TAG(macro) \
+ macro(use, USE)
+#else
+#define FOR_EACH_USE_TAG(macro)
+#endif
+
+#define FOR_EACH_TAG(macro) \
+ FOR_EACH_ANIMATION_TAG(macro) \
+ FOR_EACH_FILTERS_TAG(macro) \
+ FOR_EACH_FONTS_TAG(macro) \
+ FOR_EACH_FOREIGN_OBJECT_TAG(macro) \
+ FOR_EACH_USE_TAG(macro) \
+ macro(a, A) \
+ macro(altGlyph, ALTGLYPH) \
+ macro(circle, CIRCLE) \
+ macro(clipPath, CLIPPATH) \
+ macro(cursor, CURSOR) \
+ macro(defs, DEFS) \
+ macro(desc, DESC) \
+ macro(ellipse, ELLIPSE) \
+ macro(g, G) \
+ macro(glyph, GLYPH) \
+ macro(image, IMAGE) \
+ macro(linearGradient, LINEARGRADIENT) \
+ macro(line, LINE) \
+ macro(marker, MARKER) \
+ macro(mask, MASK) \
+ macro(metadata, METADATA) \
+ macro(path, PATH) \
+ macro(pattern, PATTERN) \
+ macro(polyline, POLYLINE) \
+ macro(polygon, POLYGON) \
+ macro(radialGradient, RADIALGRADIENT) \
+ macro(rect, RECT) \
+ macro(script, SCRIPT) \
+ macro(stop, STOP) \
+ macro(style, STYLE) \
+ macro(svg, SVG) \
+ macro(switch, SWITCH) \
+ macro(symbol, SYMBOL) \
+ macro(text, TEXT) \
+ macro(textPath, TEXTPATH) \
+ macro(title, TITLE) \
+ macro(tref, TREF) \
+ macro(tspan, TSPAN) \
+ macro(view, VIEW) \
+ // end of macro
+
+V8ClassIndex::V8WrapperType V8Proxy::GetSVGElementType(SVGElement* element)
+{
+ static HashMap<String, V8ClassIndex::V8WrapperType> map;
+ if (map.isEmpty()) {
+#define ADD_TO_HASH_MAP(tag, name) \
+ map.set(#tag, V8ClassIndex::SVG##name##ELEMENT);
+FOR_EACH_TAG(ADD_TO_HASH_MAP)
+#undef ADD_TO_HASH_MAP
+ }
+
+ V8ClassIndex::V8WrapperType t = map.get(element->localName().impl());
+ if (t == 0) return V8ClassIndex::SVGELEMENT;
+ return t;
+}
+#undef FOR_EACH_TAG
+
+#endif // ENABLE(SVG)
+
+
+v8::Handle<v8::Value> V8Proxy::EventToV8Object(Event* event)
+{
+ if (!event)
+ return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(event);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type = V8ClassIndex::EVENT;
+
+ if (event->isUIEvent()) {
+ if (event->isKeyboardEvent())
+ type = V8ClassIndex::KEYBOARDEVENT;
+ else if (event->isTextEvent())
+ type = V8ClassIndex::TEXTEVENT;
+ else if (event->isMouseEvent())
+ type = V8ClassIndex::MOUSEEVENT;
+ else if (event->isWheelEvent())
+ type = V8ClassIndex::WHEELEVENT;
+#if ENABLE(SVG)
+ else if (event->isSVGZoomEvent())
+ type = V8ClassIndex::SVGZOOMEVENT;
+#endif
+ else
+ type = V8ClassIndex::UIEVENT;
+ } else if (event->isMutationEvent())
+ type = V8ClassIndex::MUTATIONEVENT;
+ else if (event->isOverflowEvent())
+ type = V8ClassIndex::OVERFLOWEVENT;
+ else if (event->isMessageEvent())
+ type = V8ClassIndex::MESSAGEEVENT;
+ else if (event->isProgressEvent()) {
+ if (event->isXMLHttpRequestProgressEvent())
+ type = V8ClassIndex::XMLHTTPREQUESTPROGRESSEVENT;
+ else
+ type = V8ClassIndex::PROGRESSEVENT;
+ } else if (event->isWebKitAnimationEvent())
+ type = V8ClassIndex::WEBKITANIMATIONEVENT;
+ else if (event->isWebKitTransitionEvent())
+ type = V8ClassIndex::WEBKITTRANSITIONEVENT;
+
+
+ v8::Handle<v8::Object> result =
+ InstantiateV8Object(type, V8ClassIndex::EVENT, event);
+ if (result.IsEmpty()) {
+ // Instantiation failed. Avoid updating the DOM object map and
+ // return null which is already handled by callers of this function
+ // in case the event is NULL.
+ return v8::Null();
+ }
+
+ event->ref(); // fast ref
+ SetJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result));
+
+ return result;
+}
+
+
+// Caller checks node is not null.
+v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node)
+{
+ if (!node) return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMNodeMap().get(node);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ bool is_document = false; // document type node has special handling
+ V8ClassIndex::V8WrapperType type;
+
+ switch (node->nodeType()) {
+ case Node::ELEMENT_NODE:
+ if (node->isHTMLElement())
+ type = GetHTMLElementType(static_cast<HTMLElement*>(node));
+#if ENABLE(SVG)
+ else if (node->isSVGElement())
+ type = GetSVGElementType(static_cast<SVGElement*>(node));
+#endif
+ else
+ type = V8ClassIndex::ELEMENT;
+ break;
+ case Node::ATTRIBUTE_NODE:
+ type = V8ClassIndex::ATTR;
+ break;
+ case Node::TEXT_NODE:
+ type = V8ClassIndex::TEXT;
+ break;
+ case Node::CDATA_SECTION_NODE:
+ type = V8ClassIndex::CDATASECTION;
+ break;
+ case Node::ENTITY_NODE:
+ type = V8ClassIndex::ENTITY;
+ break;
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ type = V8ClassIndex::PROCESSINGINSTRUCTION;
+ break;
+ case Node::COMMENT_NODE:
+ type = V8ClassIndex::COMMENT;
+ break;
+ case Node::DOCUMENT_NODE: {
+ is_document = true;
+ Document* doc = static_cast<Document*>(node);
+ if (doc->isHTMLDocument())
+ type = V8ClassIndex::HTMLDOCUMENT;
+#if ENABLE(SVG)
+ else if (doc->isSVGDocument())
+ type = V8ClassIndex::SVGDOCUMENT;
+#endif
+ else
+ type = V8ClassIndex::DOCUMENT;
+ break;
+ }
+ case Node::DOCUMENT_TYPE_NODE:
+ type = V8ClassIndex::DOCUMENTTYPE;
+ break;
+ case Node::NOTATION_NODE:
+ type = V8ClassIndex::NOTATION;
+ break;
+ case Node::DOCUMENT_FRAGMENT_NODE:
+ type = V8ClassIndex::DOCUMENTFRAGMENT;
+ break;
+ case Node::ENTITY_REFERENCE_NODE:
+ type = V8ClassIndex::ENTITYREFERENCE;
+ break;
+ default:
+ type = V8ClassIndex::NODE;
+ }
+
+ // Find the context to which the node belongs and create the wrapper
+ // in that context. If the node is not in a document, the current
+ // context is used.
+ v8::Local<v8::Context> context;
+ Document* doc = node->document();
+ if (doc) {
+ context = V8Proxy::GetContext(doc->frame());
+ }
+ if (!context.IsEmpty()) {
+ context->Enter();
+ }
+
+ v8::Local<v8::Object> result =
+ InstantiateV8Object(type, V8ClassIndex::NODE, node);
+
+ // Exit the node's context if it was entered.
+ if (!context.IsEmpty()) {
+ context->Exit();
+ }
+
+ if (result.IsEmpty()) {
+ // If instantiation failed it's important not to add the result
+ // to the DOM node map. Instead we return an empty handle, which
+ // should already be handled by callers of this function in case
+ // the node is NULL.
+ return result;
+ }
+
+ node->ref();
+ SetJSWrapperForDOMNode(node, v8::Persistent<v8::Object>::New(result));
+
+ if (is_document) {
+ Document* doc = static_cast<Document*>(node);
+ V8Proxy* proxy = V8Proxy::retrieve(doc->frame());
+ if (proxy)
+ proxy->UpdateDocumentWrapper(result);
+
+ if (type == V8ClassIndex::HTMLDOCUMENT) {
+ // Create marker object and insert it in two internal fields.
+ // This is used to implement temporary shadowing of
+ // document.all.
+ ASSERT(result->InternalFieldCount() ==
+ V8Custom::kHTMLDocumentInternalFieldCount);
+ v8::Local<v8::Object> marker = v8::Object::New();
+ result->SetInternalField(V8Custom::kHTMLDocumentMarkerIndex, marker);
+ result->SetInternalField(V8Custom::kHTMLDocumentShadowIndex, marker);
+ }
+ }
+
+ return result;
+}
+
+
+// A JS object of type EventTarget can only be the following possible types:
+// 1) EventTargetNode; 2) XMLHttpRequest; 3) MessagePort; 4) SVGElementInstance;
+// 5) XMLHttpRequestUpload 6) Worker
+// check EventTarget.h for new type conversion methods
+v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target)
+{
+ if (!target)
+ return v8::Null();
+
+#if ENABLE(SVG)
+ SVGElementInstance* instance = target->toSVGElementInstance();
+ if (instance)
+ return ToV8Object(V8ClassIndex::SVGELEMENTINSTANCE, instance);
+#endif
+
+#if ENABLE(WORKERS)
+ Worker* worker = target->toWorker();
+ if (worker)
+ return ToV8Object(V8ClassIndex::WORKER, worker);
+#endif // WORKERS
+
+ Node* node = target->toNode();
+ if (node)
+ return NodeToV8Object(node);
+
+ // XMLHttpRequest is created within its JS counterpart.
+ XMLHttpRequest* xhr = target->toXMLHttpRequest();
+ if (xhr) {
+ v8::Handle<v8::Object> wrapper = getActiveDOMObjectMap().get(xhr);
+ ASSERT(!wrapper.IsEmpty());
+ return wrapper;
+ }
+
+ // MessagePort is created within its JS counterpart
+ MessagePort* port = target->toMessagePort();
+ if (port) {
+ v8::Handle<v8::Object> wrapper = getActiveDOMObjectMap().get(port);
+ ASSERT(!wrapper.IsEmpty());
+ return wrapper;
+ }
+
+ XMLHttpRequestUpload* upload = target->toXMLHttpRequestUpload();
+ if (upload) {
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(upload);
+ ASSERT(!wrapper.IsEmpty());
+ return wrapper;
+ }
+
+ ASSERT(0);
+ return v8::Handle<v8::Value>();
+}
+
+
+v8::Handle<v8::Value> V8Proxy::EventListenerToV8Object(
+ EventListener* listener)
+{
+ if (listener == 0) return v8::Null();
+
+ // TODO(fqian): can a user take a lazy event listener and set to other places?
+ V8AbstractEventListener* v8listener =
+ static_cast<V8AbstractEventListener*>(listener);
+ return v8listener->getListenerObject();
+}
+
+
+v8::Handle<v8::Value> V8Proxy::DOMImplementationToV8Object(
+ DOMImplementation* impl)
+{
+ v8::Handle<v8::Object> result =
+ InstantiateV8Object(V8ClassIndex::DOMIMPLEMENTATION,
+ V8ClassIndex::DOMIMPLEMENTATION,
+ impl);
+ if (result.IsEmpty()) {
+ // If the instantiation failed, we ignore it and return null instead
+ // of returning an empty handle.
+ return v8::Null();
+ }
+ return result;
+}
+
+
+v8::Handle<v8::Value> V8Proxy::StyleSheetToV8Object(StyleSheet* sheet)
+{
+ if (!sheet) return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(sheet);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type = V8ClassIndex::STYLESHEET;
+ if (sheet->isCSSStyleSheet())
+ type = V8ClassIndex::CSSSTYLESHEET;
+
+ v8::Handle<v8::Object> result =
+ InstantiateV8Object(type, V8ClassIndex::STYLESHEET, sheet);
+ if (!result.IsEmpty()) {
+ // Only update the DOM object map if the result is non-empty.
+ sheet->ref();
+ SetJSWrapperForDOMObject(sheet, v8::Persistent<v8::Object>::New(result));
+ }
+
+ // Add a hidden reference from stylesheet object to its owner node.
+ Node* owner_node = sheet->ownerNode();
+ if (owner_node) {
+ v8::Handle<v8::Object> owner =
+ v8::Handle<v8::Object>::Cast(NodeToV8Object(owner_node));
+ result->SetInternalField(V8Custom::kStyleSheetOwnerNodeIndex, owner);
+ }
+
+ return result;
+}
+
+
+v8::Handle<v8::Value> V8Proxy::CSSValueToV8Object(CSSValue* value)
+{
+ if (!value) return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(value);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type;
+
+ if (value->isWebKitCSSTransformValue())
+ type = V8ClassIndex::WEBKITCSSTRANSFORMVALUE;
+ else if (value->isValueList())
+ type = V8ClassIndex::CSSVALUELIST;
+ else if (value->isPrimitiveValue())
+ type = V8ClassIndex::CSSPRIMITIVEVALUE;
+#if ENABLE(SVG)
+ else if (value->isSVGPaint())
+ type = V8ClassIndex::SVGPAINT;
+ else if (value->isSVGColor())
+ type = V8ClassIndex::SVGCOLOR;
+#endif
+ else
+ type = V8ClassIndex::CSSVALUE;
+
+ v8::Handle<v8::Object> result =
+ InstantiateV8Object(type, V8ClassIndex::CSSVALUE, value);
+ if (!result.IsEmpty()) {
+ // Only update the DOM object map if the result is non-empty.
+ value->ref();
+ SetJSWrapperForDOMObject(value, v8::Persistent<v8::Object>::New(result));
+ }
+
+ return result;
+}
+
+
+v8::Handle<v8::Value> V8Proxy::CSSRuleToV8Object(CSSRule* rule)
+{
+ if (!rule) return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(rule);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type;
+
+ switch (rule->type()) {
+ case CSSRule::STYLE_RULE:
+ type = V8ClassIndex::CSSSTYLERULE;
+ break;
+ case CSSRule::CHARSET_RULE:
+ type = V8ClassIndex::CSSCHARSETRULE;
+ break;
+ case CSSRule::IMPORT_RULE:
+ type = V8ClassIndex::CSSIMPORTRULE;
+ break;
+ case CSSRule::MEDIA_RULE:
+ type = V8ClassIndex::CSSMEDIARULE;
+ break;
+ case CSSRule::FONT_FACE_RULE:
+ type = V8ClassIndex::CSSFONTFACERULE;
+ break;
+ case CSSRule::PAGE_RULE:
+ type = V8ClassIndex::CSSPAGERULE;
+ break;
+ case CSSRule::VARIABLES_RULE:
+ type = V8ClassIndex::CSSVARIABLESRULE;
+ break;
+ case CSSRule::WEBKIT_KEYFRAME_RULE:
+ type = V8ClassIndex::WEBKITCSSKEYFRAMERULE;
+ break;
+ case CSSRule::WEBKIT_KEYFRAMES_RULE:
+ type = V8ClassIndex::WEBKITCSSKEYFRAMESRULE;
+ break;
+ default: // CSSRule::UNKNOWN_RULE
+ type = V8ClassIndex::CSSRULE;
+ break;
+ }
+
+ v8::Handle<v8::Object> result =
+ InstantiateV8Object(type, V8ClassIndex::CSSRULE, rule);
+ if (!result.IsEmpty()) {
+ // Only update the DOM object map if the result is non-empty.
+ rule->ref();
+ SetJSWrapperForDOMObject(rule, v8::Persistent<v8::Object>::New(result));
+ }
+ return result;
+}
+
+v8::Handle<v8::Value> V8Proxy::WindowToV8Object(DOMWindow* window)
+{
+ if (!window) return v8::Null();
+ // Initializes environment of a frame, and return the global object
+ // of the frame.
+ Frame* frame = window->frame();
+ if (!frame)
+ return v8::Handle<v8::Object>();
+
+ // Special case: Because of evaluateInNewContext() one DOMWindow can have
+ // multipe contexts and multiple global objects associated with it. When
+ // code running in one of those contexts accesses the window object, we
+ // want to return the global object associated with that context, not
+ // necessarily the first global object associated with that DOMWindow.
+ v8::Handle<v8::Context> current_context = v8::Context::GetCurrent();
+ v8::Handle<v8::Object> current_global = current_context->Global();
+ v8::Handle<v8::Object> windowWrapper =
+ LookupDOMWrapper(V8ClassIndex::DOMWINDOW, current_global);
+ if (!windowWrapper.IsEmpty())
+ if (DOMWrapperToNative<DOMWindow>(windowWrapper) == window)
+ return current_global;
+
+ // Otherwise, return the global object associated with this frame.
+ v8::Handle<v8::Context> context = GetContext(frame);
+ if (context.IsEmpty())
+ return v8::Handle<v8::Object>();
+
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+ return global;
+}
+
+void V8Proxy::BindJSObjectToWindow(Frame* frame,
+ const char* name,
+ int type,
+ v8::Handle<v8::FunctionTemplate> desc,
+ void* imp)
+{
+ // Get environment.
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(frame);
+ if (context.IsEmpty())
+ return; // JS not enabled.
+
+ v8::Context::Scope scope(context);
+ v8::Handle<v8::Object> instance = desc->GetFunction();
+ SetDOMWrapper(instance, type, imp);
+
+ v8::Handle<v8::Object> global = context->Global();
+ global->Set(v8::String::New(name), instance);
+}
+
+void V8Proxy::ProcessConsoleMessages()
+{
+ ConsoleMessageManager::ProcessDelayedMessages();
+}
+
+
+// Create the utility context for holding JavaScript functions used internally
+// which are not visible to JavaScript executing on the page.
+void V8Proxy::CreateUtilityContext() {
+ ASSERT(m_utilityContext.IsEmpty());
+
+ v8::HandleScope scope;
+ v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ m_utilityContext = v8::Context::New(NULL, global_template);
+ v8::Context::Scope context_scope(m_utilityContext);
+
+ // Compile JavaScript function for retrieving the source line of the top
+ // JavaScript stack frame.
+ static const char* frame_source_line_source =
+ "function frame_source_line(exec_state) {"
+ " return exec_state.frame(0).sourceLine();"
+ "}";
+ v8::Script::Compile(v8::String::New(frame_source_line_source))->Run();
+
+ // Compile JavaScript function for retrieving the source name of the top
+ // JavaScript stack frame.
+ static const char* frame_source_name_source =
+ "function frame_source_name(exec_state) {"
+ " var frame = exec_state.frame(0);"
+ " if (frame.func().resolved() && "
+ " frame.func().script() && "
+ " frame.func().script().name()) {"
+ " return frame.func().script().name();"
+ " }"
+ "}";
+ v8::Script::Compile(v8::String::New(frame_source_name_source))->Run();
+}
+
+
+int V8Proxy::GetSourceLineNumber() {
+#if PLATFORM(ANDROID)
+ return 0;
+#else
+ v8::HandleScope scope;
+ v8::Handle<v8::Context> utility_context = V8Proxy::GetUtilityContext();
+ if (utility_context.IsEmpty()) {
+ return 0;
+ }
+ v8::Context::Scope context_scope(utility_context);
+ v8::Handle<v8::Function> frame_source_line;
+ frame_source_line = v8::Local<v8::Function>::Cast(
+ utility_context->Global()->Get(v8::String::New("frame_source_line")));
+ if (frame_source_line.IsEmpty()) {
+ return 0;
+ }
+ v8::Handle<v8::Value> result = v8::Debug::Call(frame_source_line);
+ if (result.IsEmpty()) {
+ return 0;
+ }
+ return result->Int32Value();
+#endif
+}
+
+
+String V8Proxy::GetSourceName() {
+#if PLATFORM(ANDROID)
+ return String();
+#else
+ v8::HandleScope scope;
+ v8::Handle<v8::Context> utility_context = GetUtilityContext();
+ if (utility_context.IsEmpty()) {
+ return String();
+ }
+ v8::Context::Scope context_scope(utility_context);
+ v8::Handle<v8::Function> frame_source_name;
+ frame_source_name = v8::Local<v8::Function>::Cast(
+ utility_context->Global()->Get(v8::String::New("frame_source_name")));
+ if (frame_source_name.IsEmpty()) {
+ return String();
+ }
+ return ToWebCoreString(v8::Debug::Call(frame_source_name));
+#endif
+}
+
+void V8Proxy::RegisterExtension(v8::Extension* extension,
+ const String& schemeRestriction) {
+ v8::RegisterExtension(extension);
+ V8ExtensionInfo info = {schemeRestriction, extension};
+ m_extensions.append(info);
+}
+
+} // namespace WebCore
diff --git a/V8Binding/v8/v8_proxy.h b/V8Binding/v8/v8_proxy.h
new file mode 100644
index 0000000..45f9f39
--- /dev/null
+++ b/V8Binding/v8/v8_proxy.h
@@ -0,0 +1,645 @@
+// 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_PROXY_H__
+#define V8_PROXY_H__
+
+#include <v8.h>
+#include "v8_index.h"
+#include "v8_custom.h"
+#include "v8_utility.h"
+#include "Node.h"
+#include "NodeFilter.h"
+#include "PlatformString.h" // for WebCore::String
+#include "ScriptSourceCode.h" // for WebCore::ScriptSourceCode
+#include "SecurityOrigin.h" // for WebCore::SecurityOrigin
+#include "V8DOMMap.h"
+#include <wtf/Assertions.h>
+#include <wtf/PassRefPtr.h> // so generated bindings don't have to
+#include <wtf/Vector.h>
+
+#if defined(ENABLE_DOM_STATS_COUNTERS) && PLATFORM(CHROMIUM)
+#include "ChromiumBridge.h"
+#define INC_STATS(name) ChromiumBridge::incrementStatsCounter(name)
+#else
+#define INC_STATS(name)
+#endif
+
+// FIXME: Remove the following hack when we replace all references to GetDOMObjectMap.
+#define GetDOMObjectMap getDOMObjectMap
+
+namespace WebCore {
+
+class CSSStyleDeclaration;
+class DOMImplementation;
+class Element;
+class Event;
+class EventListener;
+class Frame;
+class HTMLCollection;
+class HTMLOptionsCollection;
+class HTMLElement;
+class HTMLDocument;
+class MediaList;
+class NamedNodeMap;
+class Node;
+class NodeList;
+class Screen;
+class String;
+class StyleSheet;
+class SVGElement;
+class DOMWindow;
+class Document;
+class EventTarget;
+class Event;
+class EventListener;
+class Navigator;
+class MimeType;
+class MimeTypeArray;
+class Plugin;
+class PluginArray;
+class StyleSheetList;
+class CSSValue;
+class CSSRule;
+class CSSRuleList;
+class CSSValueList;
+class NodeFilter;
+class ScriptExecutionContext;
+
+#if ENABLE(SVG)
+class SVGElementInstance;
+#endif
+
+class V8EventListener;
+class V8ObjectEventListener;
+
+// This is a container for V8EventListener objects that also does some
+// caching to speed up finding entries by v8::Object.
+class V8EventListenerList {
+ public:
+ static const size_t kMaxKeyNameLength = 254;
+ // The name should be distinct from any other V8EventListenerList
+ // within the same process, and <= kMaxKeyNameLength characters.
+ explicit V8EventListenerList(const char* name);
+ ~V8EventListenerList();
+
+ typedef Vector<V8EventListener*>::iterator iterator;
+ V8EventListenerList::iterator begin();
+ iterator end();
+
+ // In addition to adding the listener to this list, this also caches the
+ // V8EventListener as a hidden property on its wrapped v8 listener object,
+ // so we can quickly look it up later.
+ void add(V8EventListener*);
+ void remove(V8EventListener*);
+ V8EventListener* find(v8::Local<v8::Object>, bool isInline);
+ void clear();
+
+ private:
+ v8::Handle<v8::String> getKey(bool isInline);
+ v8::Persistent<v8::String> m_inlineKey;
+ v8::Persistent<v8::String> m_nonInlineKey;
+ Vector<V8EventListener*> m_list;
+};
+
+
+// TODO(fqian): use standard logging facilities in WebCore.
+void log_info(Frame* frame, const String& msg, const String& url);
+
+
+#ifndef NDEBUG
+
+#define GlobalHandleTypeList(V) \
+ V(PROXY) \
+ V(NPOBJECT) \
+ V(SCHEDULED_ACTION) \
+ V(EVENT_LISTENER) \
+ V(NODE_FILTER) \
+ V(SCRIPTINSTANCE) \
+ V(SCRIPTVALUE)
+
+
+// Host information of persistent handles.
+enum GlobalHandleType {
+#define ENUM(name) name,
+ GlobalHandleTypeList(ENUM)
+#undef ENUM
+};
+
+
+class GlobalHandleInfo {
+ public:
+ GlobalHandleInfo(void* host, GlobalHandleType type)
+ : host_(host), type_(type) { }
+ void* host_;
+ GlobalHandleType type_;
+};
+
+#endif // NDEBUG
+
+// The following Batch structs and methods are used for setting multiple
+// properties on an ObjectTemplate, used from the generated bindings
+// initialization (ConfigureXXXTemplate). This greatly reduces the binary
+// size by moving from code driven setup to data table driven setup.
+
+// BatchedAttribute translates into calls to SetAccessor() on either the
+// instance or the prototype ObjectTemplate, based on |on_proto|.
+struct BatchedAttribute {
+ const char* const name;
+ v8::AccessorGetter getter;
+ v8::AccessorSetter setter;
+ V8ClassIndex::V8WrapperType data;
+ v8::AccessControl settings;
+ v8::PropertyAttribute attribute;
+ bool on_proto;
+};
+
+void BatchConfigureAttributes(v8::Handle<v8::ObjectTemplate> inst,
+ v8::Handle<v8::ObjectTemplate> proto,
+ const BatchedAttribute* attrs,
+ size_t num_attrs);
+
+// BatchedConstant translates into calls to Set() for setting up an object's
+// constants. It sets the constant on both the FunctionTemplate |desc| and the
+// ObjectTemplate |proto|. PropertyAttributes is always ReadOnly.
+struct BatchedConstant {
+ const char* const name;
+ int value;
+};
+
+void BatchConfigureConstants(v8::Handle<v8::FunctionTemplate> desc,
+ v8::Handle<v8::ObjectTemplate> proto,
+ const BatchedConstant* consts,
+ size_t num_consts);
+
+const int kMaxRecursionDepth = 20;
+
+// Information about an extension that is registered for use with V8. If scheme
+// is non-empty, it contains the URL scheme the extension should be used with.
+// Otherwise, the extension is used with all schemes.
+struct V8ExtensionInfo {
+ String scheme;
+ v8::Extension* extension;
+};
+typedef WTF::Vector<V8ExtensionInfo> V8ExtensionList;
+
+class V8Proxy {
+ public:
+ // The types of javascript errors that can be thrown.
+ enum ErrorType {
+ RANGE_ERROR,
+ REFERENCE_ERROR,
+ SYNTAX_ERROR,
+ TYPE_ERROR,
+ GENERAL_ERROR
+ };
+
+ explicit V8Proxy(Frame* frame)
+ : m_frame(frame), m_event_listeners("m_event_listeners"),
+ m_xhr_listeners("m_xhr_listeners"), m_inlineCode(false),
+ m_timerCallback(false), m_recursion(0) { }
+
+ ~V8Proxy();
+
+ Frame* frame() { return m_frame; }
+
+ // Clear page-specific data, but keep the global object identify.
+ void clearForNavigation();
+
+ // Clear page-specific data before shutting down the proxy object.
+ void clearForClose();
+
+ // Update document object of the frame.
+ void updateDocument();
+
+ // Update the security origin of a document
+ // (e.g., after setting docoument.domain).
+ void updateSecurityOrigin();
+
+ // Destroy the global object.
+ void DestroyGlobal();
+
+ // TODO(mpcomplete): Need comment. User Gesture related.
+ bool inlineCode() const { return m_inlineCode; }
+ void setInlineCode(bool value) { m_inlineCode = value; }
+
+ bool timerCallback() const { return m_timerCallback; }
+ void setTimerCallback(bool value) { m_timerCallback = value; }
+
+ // Has the context for this proxy been initialized?
+ bool ContextInitialized();
+
+ // Disconnects the proxy from its owner frame,
+ // and clears all timeouts on the DOM window.
+ void disconnectFrame();
+
+ bool isEnabled();
+
+ // Find/Create/Remove event listener wrappers.
+ PassRefPtr<V8EventListener> FindV8EventListener(v8::Local<v8::Value> listener,
+ bool html);
+ PassRefPtr<V8EventListener> FindOrCreateV8EventListener(v8::Local<v8::Value> listener,
+ bool html);
+
+ PassRefPtr<V8EventListener> FindObjectEventListener(v8::Local<v8::Value> listener,
+ bool html);
+ PassRefPtr<V8EventListener> FindOrCreateObjectEventListener(v8::Local<v8::Value> listener,
+ bool html);
+
+ void RemoveV8EventListener(V8EventListener* listener);
+ void RemoveObjectEventListener(V8ObjectEventListener* listener);
+
+ // Protect/Unprotect JS wrappers of a DOM object.
+ static void GCProtect(void* dom_object);
+ static void GCUnprotect(void* dom_object);
+
+ // Create a lazy event listener.
+ PassRefPtr<EventListener> createInlineEventListener(
+ const String& functionName, const String& code, Node* node);
+#if ENABLE(SVG)
+ PassRefPtr<EventListener> createSVGEventHandler(
+ const String& functionName, const String& code, Node* node);
+
+ static void SetSVGContext(void* object, SVGElement* context);
+ static SVGElement* GetSVGContext(void* object);
+#endif
+
+ void setEventHandlerLineno(int lineno) { m_handlerLineno = lineno; }
+ void finishedWithEvent(Event* event) { }
+
+ // Evaluate JavaScript in a new context. The script gets its own global scope
+ // and its own prototypes for intrinsic JavaScript objects (String, Array,
+ // and so-on). It shares the wrappers for all DOM nodes and DOM constructors.
+ void evaluateInNewContext(const Vector<ScriptSourceCode>& sources);
+
+ // Evaluate a script file in the current execution environment.
+ // The caller must hold an execution context.
+ // If cannot evalute the script, it returns an error.
+ v8::Local<v8::Value> evaluate(const ScriptSourceCode& source,
+ Node* node);
+
+ // Run an already compiled script.
+ v8::Local<v8::Value> RunScript(v8::Handle<v8::Script> script,
+ bool inline_code);
+
+ // Call the function with the given receiver and arguments.
+ v8::Local<v8::Value> CallFunction(v8::Handle<v8::Function> function,
+ v8::Handle<v8::Object> receiver,
+ int argc,
+ v8::Handle<v8::Value> argv[]);
+
+ // Returns the dom constructor function for the given node type.
+ v8::Local<v8::Function> GetConstructor(V8ClassIndex::V8WrapperType type);
+
+ // To create JS Wrapper objects, we create a cache of a 'boiler plate'
+ // object, and then simply Clone that object each time we need a new one.
+ // This is faster than going through the full object creation process.
+ v8::Local<v8::Object> CreateWrapperFromCache(V8ClassIndex::V8WrapperType type);
+
+ // Returns the window object of the currently executing context.
+ static DOMWindow* retrieveWindow();
+ // Returns the window object associated with a context.
+ static DOMWindow* retrieveWindow(v8::Handle<v8::Context> context);
+ // Returns V8Proxy object of the currently executing context.
+ static V8Proxy* retrieve();
+ // Returns V8Proxy object associated with a frame.
+ static V8Proxy* retrieve(Frame* frame);
+ // Returns V8Proxy object associated with a script execution context.
+ static V8Proxy* retrieve(ScriptExecutionContext* context);
+
+ // Returns the frame object of the window object associated
+ // with the currently executing context.
+ static Frame* retrieveFrame();
+ // Returns the frame object of the window object associated with
+ // a context.
+ static Frame* retrieveFrame(v8::Handle<v8::Context> context);
+ // Returns the frame that started JS execution.
+ // NOTE: cannot declare retrieveActiveFrame as inline function,
+ // VS complains at linking time.
+ static Frame* retrieveActiveFrame();
+
+ // Returns V8 Context of a frame. If none exists, creates
+ // a new context. It is potentially slow and consumes memory.
+ static v8::Local<v8::Context> GetContext(Frame* frame);
+ static v8::Local<v8::Context> GetCurrentContext();
+
+ // If the current context causes out of memory, JavaScript setting
+ // is disabled and it returns true.
+ static bool HandleOutOfMemory();
+
+ // Check if the active execution context can access the target frame.
+ static bool CanAccessFrame(Frame* target, bool report_error);
+
+ // Check if it is safe to access the given node from the
+ // current security context.
+ static bool CheckNodeSecurity(Node* node);
+
+ static v8::Handle<v8::Value> CheckNewLegal(const v8::Arguments& args);
+
+ // Create a V8 wrapper for a C pointer
+ static v8::Handle<v8::Value> WrapCPointer(void* cptr) {
+ // Represent void* as int
+ int addr = reinterpret_cast<int>(cptr);
+ ASSERT((addr & 0x01) == 0); // the address must be aligned.
+ return v8::Integer::New(addr >> 1);
+ }
+
+ // Take C pointer out of a v8 wrapper
+ template <class C>
+ static C* ExtractCPointer(v8::Handle<v8::Value> obj) {
+ return static_cast<C*>(ExtractCPointerImpl(obj));
+ }
+
+ static v8::Handle<v8::Script> CompileScript(v8::Handle<v8::String> code,
+ const String& fileName,
+ int baseLine);
+
+#ifndef NDEBUG
+ // Checks if a v8 value can be a DOM wrapper
+ static bool MaybeDOMWrapper(v8::Handle<v8::Value> value);
+#endif
+
+ // Sets contents of a DOM wrapper.
+ static void SetDOMWrapper(v8::Handle<v8::Object> obj, int type, void* ptr);
+
+ static v8::Handle<v8::Object> LookupDOMWrapper(
+ V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> value);
+
+ // A helper function extract native object pointer from a DOM wrapper
+ // and cast to the specified type.
+ template <class C>
+ static C* DOMWrapperToNative(v8::Handle<v8::Value> object) {
+ ASSERT(MaybeDOMWrapper(object));
+ v8::Handle<v8::Value> ptr =
+ v8::Handle<v8::Object>::Cast(object)->GetInternalField(
+ V8Custom::kDOMWrapperObjectIndex);
+ return ExtractCPointer<C>(ptr);
+ }
+
+ // A help function extract a node type pointer from a DOM wrapper.
+ // Wrapped pointer must be cast to Node* first.
+ template <class C>
+ static C* DOMWrapperToNode(v8::Handle<v8::Value> value) {
+ ASSERT(MaybeDOMWrapper(value));
+
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
+
+ ASSERT(GetDOMWrapperType(object) == V8ClassIndex::NODE);
+
+ v8::Handle<v8::Value> wrapper =
+ object->GetInternalField(V8Custom::kDOMWrapperObjectIndex);
+ return static_cast<C*>(ExtractCPointer<Node>(wrapper));
+ }
+
+ template<typename T>
+ static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type, PassRefPtr<T> imp)
+ {
+ return ToV8Object(type, imp.get());
+ }
+ static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type,
+ void* imp);
+ // Fast-path for Node objects.
+ static v8::Handle<v8::Value> NodeToV8Object(Node* node);
+
+ template <class C>
+ static C* ToNativeObject(V8ClassIndex::V8WrapperType type,
+ v8::Handle<v8::Value> object) {
+ return static_cast<C*>(ToNativeObjectImpl(type, object));
+ }
+
+ static V8ClassIndex::V8WrapperType GetDOMWrapperType(
+ v8::Handle<v8::Object> object);
+
+ // If the exception code is different from zero, a DOM exception is
+ // schedule to be thrown.
+ static void SetDOMException(int exception_code);
+
+ // Schedule an error object to be thrown.
+ static v8::Handle<v8::Value> ThrowError(ErrorType type, const char* message);
+
+ // Create an instance of a function descriptor and set to the global object
+ // as a named property. Used by v8_test_shell.
+ static void BindJSObjectToWindow(Frame* frame,
+ const char* name,
+ int type,
+ v8::Handle<v8::FunctionTemplate> desc,
+ void* imp);
+
+ static v8::Handle<v8::Value> EventToV8Object(Event* event);
+ static Event* ToNativeEvent(v8::Handle<v8::Value> jsevent) {
+ if (!IsDOMEventWrapper(jsevent)) return 0;
+ return DOMWrapperToNative<Event>(jsevent);
+ }
+
+ static v8::Handle<v8::Value> EventTargetToV8Object(EventTarget* target);
+ // Wrap and unwrap JS event listeners
+ static v8::Handle<v8::Value> EventListenerToV8Object(EventListener* target);
+
+ // DOMImplementation is a singleton and it is handled in a special
+ // way. A wrapper is generated per document and stored in an
+ // internal field of the document.
+ static v8::Handle<v8::Value> DOMImplementationToV8Object(
+ DOMImplementation* impl);
+
+ // Wrap JS node filter in C++
+ static PassRefPtr<NodeFilter> ToNativeNodeFilter(v8::Handle<v8::Value> filter);
+
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate(
+ V8ClassIndex::V8WrapperType type);
+
+ template <int tag, typename T>
+ static v8::Handle<v8::Value> ConstructDOMObject(const v8::Arguments& args);
+
+ // Checks whether a DOM object has a JS wrapper.
+ static bool DOMObjectHasJSWrapper(void* obj);
+ // Set JS wrapper of a DOM object, the caller in charge of increase ref.
+ static void SetJSWrapperForDOMObject(void* obj,
+ v8::Persistent<v8::Object> wrapper);
+ static void SetJSWrapperForActiveDOMObject(void* obj,
+ v8::Persistent<v8::Object> wrapper);
+ static void SetJSWrapperForDOMNode(Node* node,
+ v8::Persistent<v8::Object> wrapper);
+
+ // Process any pending JavaScript console messages.
+ static void ProcessConsoleMessages();
+
+#ifndef NDEBUG
+ // For debugging and leak detection purpose
+ static void RegisterGlobalHandle(GlobalHandleType type,
+ void* host,
+ v8::Persistent<v8::Value> handle);
+ static void UnregisterGlobalHandle(void* host,
+ v8::Persistent<v8::Value> handle);
+#endif
+
+ // Check whether a V8 value is a wrapper of type |classType|.
+ static bool IsWrapperOfType(v8::Handle<v8::Value> obj,
+ V8ClassIndex::V8WrapperType classType);
+
+ // Function for retrieving the line number and source name for the top
+ // JavaScript stack frame.
+ static int GetSourceLineNumber();
+ static String GetSourceName();
+
+
+ // Returns a local handle of the context.
+ v8::Local<v8::Context> GetContext() {
+ return v8::Local<v8::Context>::New(m_context);
+ }
+
+ // Registers an extension to be available on webpages with a particular scheme
+ // If the scheme argument is empty, the extension is available on all pages.
+ // Will only affect v8 contexts initialized after this call. Takes ownership
+ // of the v8::Extension object passed.
+ static void RegisterExtension(v8::Extension* extension,
+ const String& schemeRestriction);
+
+ private:
+ v8::Persistent<v8::Context> createNewContext(v8::Handle<v8::Object> global);
+ void InitContextIfNeeded();
+ void DisconnectEventListeners();
+ void SetSecurityToken();
+ void ClearDocumentWrapper();
+ void UpdateDocumentWrapper(v8::Handle<v8::Value> wrapper);
+ // Dispose global handles of m_contexts and friends.
+ void DisposeContextHandles();
+
+ static bool CanAccessPrivate(DOMWindow* target);
+
+ // Check whether a V8 value is a DOM Event wrapper
+ static bool IsDOMEventWrapper(v8::Handle<v8::Value> obj);
+
+ static void* ToNativeObjectImpl(V8ClassIndex::V8WrapperType type,
+ v8::Handle<v8::Value> object);
+
+ // Take C pointer out of a v8 wrapper
+ static void* ExtractCPointerImpl(v8::Handle<v8::Value> obj) {
+ ASSERT(obj->IsNumber());
+ int addr = obj->Int32Value();
+ return reinterpret_cast<void*>(addr << 1);
+ }
+
+
+ static v8::Handle<v8::Value> StyleSheetToV8Object(StyleSheet* sheet);
+ static v8::Handle<v8::Value> CSSValueToV8Object(CSSValue* value);
+ static v8::Handle<v8::Value> CSSRuleToV8Object(CSSRule* rule);
+ // Returns the JS wrapper of a window object, initializes the environment
+ // of the window frame if needed.
+ static v8::Handle<v8::Value> WindowToV8Object(DOMWindow* window);
+
+#if ENABLE(SVG)
+ static v8::Handle<v8::Value> SVGElementInstanceToV8Object(
+ SVGElementInstance* instance);
+ static v8::Handle<v8::Value> SVGObjectWithContextToV8Object(
+ V8ClassIndex::V8WrapperType type, void* object);
+#endif
+
+ // Set hidden references in a DOMWindow object of a frame.
+ static void SetHiddenWindowReference(Frame* frame,
+ const int internal_index,
+ v8::Handle<v8::Object> jsobj);
+
+ static V8ClassIndex::V8WrapperType GetHTMLElementType(HTMLElement* elm);
+
+ // The first parameter, desc_type, specifies the function descriptor
+ // used to create JS object. The second parameter, cptr_type, specifies
+ // the type of third parameter, impl, for type casting.
+ // For example, a HTML element has HTMLELEMENT desc_type, but always
+ // use NODE as cptr_type. JS wrapper stores cptr_type and impl as
+ // internal fields.
+ static v8::Local<v8::Object> InstantiateV8Object(
+ V8ClassIndex::V8WrapperType desc_type,
+ V8ClassIndex::V8WrapperType cptr_type,
+ void* impl);
+
+ static const char* GetRangeExceptionName(int exception_code);
+ static const char* GetEventExceptionName(int exception_code);
+ static const char* GetXMLHttpRequestExceptionName(int exception_code);
+ static const char* GetDOMExceptionName(int exception_code);
+
+#if ENABLE(XPATH)
+ static const char* GetXPathExceptionName(int exception_code);
+#endif
+
+#if ENABLE(SVG)
+ static V8ClassIndex::V8WrapperType GetSVGElementType(SVGElement* elm);
+ static const char* GetSVGExceptionName(int exception_code);
+#endif
+
+ // Create and populate the utility context.
+ static void CreateUtilityContext();
+
+ // Returns a local handle of the utility context.
+ static v8::Local<v8::Context> GetUtilityContext() {
+ if (m_utilityContext.IsEmpty()) {
+ CreateUtilityContext();
+ }
+ return v8::Local<v8::Context>::New(m_utilityContext);
+ }
+
+ Frame* m_frame;
+
+ v8::Persistent<v8::Context> m_context;
+ // For each possible type of wrapper, we keep a boilerplate object.
+ // The boilerplate is used to create additional wrappers of the same type.
+ // We keep a single persistent handle to an array of the activated
+ // boilerplates.
+ v8::Persistent<v8::Array> m_wrapper_boilerplates;
+ v8::Persistent<v8::Value> m_object_prototype;
+
+ v8::Persistent<v8::Object> m_global;
+ v8::Persistent<v8::Value> m_document;
+
+ // Utility context holding JavaScript functions used internally.
+ static v8::Persistent<v8::Context> m_utilityContext;
+
+ int m_handlerLineno;
+
+ // A list of event listeners created for this frame,
+ // the list gets cleared when removing all timeouts.
+ V8EventListenerList m_event_listeners;
+
+ // A list of event listeners create for XMLHttpRequest object for this frame,
+ // the list gets cleared when removing all timeouts.
+ V8EventListenerList m_xhr_listeners;
+
+ // True for <a href="javascript:foo()"> and false for <script>foo()</script>.
+ // Only valid during execution.
+ bool m_inlineCode;
+
+ // True when executing from within a timer callback. Only valid during
+ // execution.
+ bool m_timerCallback;
+
+ // Track the recursion depth to be able to avoid too deep recursion. The V8
+ // engine allows much more recursion than KJS does so we need to guard against
+ // excessive recursion in the binding layer.
+ int m_recursion;
+
+ // List of extensions registered with the context.
+ static V8ExtensionList m_extensions;
+};
+
+template <int tag, typename T>
+v8::Handle<v8::Value> V8Proxy::ConstructDOMObject(const v8::Arguments& args) {
+ if (!args.IsConstructCall()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR,
+ "DOM object constructor cannot be called as a function.");
+ return v8::Undefined();
+ }
+
+
+ // Note: it's OK to let this RefPtr go out of scope because we also call
+ // SetDOMWrapper(), which effectively holds a reference to obj.
+ RefPtr<T> obj = T::create();
+ V8Proxy::SetDOMWrapper(args.Holder(), tag, obj.get());
+ obj->ref();
+ V8Proxy::SetJSWrapperForDOMObject(
+ obj.get(), v8::Persistent<v8::Object>::New(args.Holder()));
+ return args.Holder();
+}
+
+} // namespace WebCore
+
+#endif // V8_PROXY_H__
diff --git a/V8Binding/v8/v8_utility.h b/V8Binding/v8/v8_utility.h
new file mode 100644
index 0000000..620c04c
--- /dev/null
+++ b/V8Binding/v8/v8_utility.h
@@ -0,0 +1,58 @@
+// 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_UTILITY_H__
+#define V8_UTILITY_H__
+
+namespace WebCore {
+
+class AllowAllocation {
+ public:
+ inline AllowAllocation() {
+ m_prev = m_current;
+ m_current = true;
+ }
+ inline ~AllowAllocation() {
+ m_current = m_prev;
+ }
+ static bool m_current;
+ private:
+ bool m_prev;
+};
+
+class SafeAllocation {
+ public:
+ static inline v8::Local<v8::Object> NewInstance(
+ v8::Handle<v8::Function> fun);
+ static inline v8::Local<v8::Object> NewInstance(
+ v8::Handle<v8::ObjectTemplate> templ);
+ static inline v8::Local<v8::Object> NewInstance(
+ v8::Handle<v8::Function> fun, int argc, v8::Handle<v8::Value> argv[]);
+};
+
+v8::Local<v8::Object> SafeAllocation::NewInstance(
+ v8::Handle<v8::Function> fun) {
+ if (fun.IsEmpty())
+ return v8::Local<v8::Object>();
+ AllowAllocation allow;
+ return fun->NewInstance();
+}
+
+v8::Local<v8::Object> SafeAllocation::NewInstance(
+ v8::Handle<v8::ObjectTemplate> templ) {
+ if (templ.IsEmpty()) return v8::Local<v8::Object>();
+ AllowAllocation allow;
+ return templ->NewInstance();
+}
+
+v8::Local<v8::Object> SafeAllocation::NewInstance(
+ v8::Handle<v8::Function> fun, int argc, v8::Handle<v8::Value> argv[]) {
+ if (fun.IsEmpty()) return v8::Local<v8::Object>();
+ AllowAllocation allow;
+ return fun->NewInstance(argc, argv);
+}
+
+} // namespace WebCore
+
+#endif // V8_UTILITY_H__