From 540cd05d3656ead7ac1e16b1ac2426cc2d1df252 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Mon, 7 Mar 2016 11:10:56 +0100 Subject: Some more preparations for current V8 API --- CMakeLists.txt | 40 +- contrib/build-scripts/build-v8-linux.sh | 115 ++- contrib/build-scripts/build-v8-macosx.sh | 108 ++- contrib/build-scripts/build-v8-windows.bat | 87 ++ contrib/build-scripts/platform-id-linux.sh | 4 + .../dom/scripts/CodeGeneratorArabicaV8-pre3.14.pm | 1023 -------------------- contrib/dom/scripts/CodeGeneratorArabicaV8.pm.new | 1018 ------------------- .../dom/scripts/CodeGeneratorArabicaV8.post3.14.pm | 1021 +++++++++++++++++++ src/uscxml/Interpreter.h | 2 +- src/uscxml/URL.h | 2 +- src/uscxml/messages/Blob.h | 2 +- src/uscxml/plugins/DataModel.h | 2 +- src/uscxml/plugins/ExecutableContent.h | 2 +- src/uscxml/plugins/IOProcessor.h | 2 +- src/uscxml/plugins/Invoker.h | 2 +- .../plugins/datamodel/ecmascript/TypedArray.cpp | 2 +- src/uscxml/transform/Transformer.h | 2 +- 17 files changed, 1328 insertions(+), 2106 deletions(-) create mode 100644 contrib/build-scripts/build-v8-windows.bat delete mode 100644 contrib/dom/scripts/CodeGeneratorArabicaV8-pre3.14.pm delete mode 100644 contrib/dom/scripts/CodeGeneratorArabicaV8.pm.new create mode 100644 contrib/dom/scripts/CodeGeneratorArabicaV8.post3.14.pm diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b65fc9..707e991 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -539,14 +539,21 @@ if (APPLE) endif() # see http://www.mail-archive.com/cmake@cmake.org/msg23240.html -if (APPLE AND MACOSX_VERSION VERSION_LESS "10.9") - # figure out what to do with Mavericks (10.9) later -# add_definitions("-D_DARWIN_UNLIMITED_SELECT") - # support leopard and above - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) - foreach(FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS) - set(${FLAGS} "${${FLAGS}} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") - endforeach() +if (APPLE) + if (MACOSX_VERSION VERSION_LESS "10.9") + # figure out what to do with Mavericks (10.9) later + # add_definitions("-D_DARWIN_UNLIMITED_SELECT") + # support leopard and above + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) + foreach(FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS) + set(${FLAGS} "${${FLAGS}} -stdlib=libstdc++ -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endforeach() + else() + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7) + foreach(FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS) + set(${FLAGS} "${${FLAGS}} -stdlib=libc++ -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endforeach() + endif() endif() # if (APPLE AND MACOSX_VERSION VERSION_GREATER "10.9.99") @@ -1159,7 +1166,16 @@ list(SORT USCXML_TRANSFORM_FILES) # we cannot define source groups in sub directories! foreach( FILE ${ALL_SOURCE_FILES} ) get_filename_component(PATH ${FILE} PATH) - + get_filename_component(NAME ${FILE} NAME) + + # if (${NAME} MATCHES "Factory.cpp") + # set_property(SOURCE ${FILE} PROPERTY COMPILE_FLAGS -std=c++11) + # endif() + # if (${PATH} MATCHES ".*datamodel\\/ecmascript\\/v8\\/*") + # set_property(SOURCE ${FILE} PROPERTY COMPILE_FLAGS -std=c++11) + # # message(${FILE}) + # endif() + if (${PATH} MATCHES ".*datamodel\\/ecmascript.*") STRING(REGEX MATCH "[^\\/]*$" COMP_NAME ${PATH}) if (COMP_NAME STREQUAL "ecmascript") @@ -1215,6 +1231,10 @@ foreach( FILE ${ALL_SOURCE_FILES} ) endif() endforeach() +# if (V8_FOUND AND BUILD_DM_ECMA) +# set_property(SOURCE ${ALL_SOURCE_FILES} PROPERTY COMPILE_FLAGS -Wno-c++11-extensions) +# endif() + # add compile time reducer # see https://github.com/sakra/cotire if (ENABLE_COTIRE) @@ -1247,7 +1267,7 @@ if (BUILD_AS_PLUGINS) set_target_properties(uscxml PROPERTIES COMPILE_FLAGS "-DUSCXML_EXPORT") # set_target_properties(uscxml PROPERTIES COMPILE_FLAGS "-DPLUMA_EXPORTS") add_definitions(-DPLUMA_EXPORTS) -else() +else() add_library(uscxml ${USCXML_FILES}) target_link_libraries(uscxml ${USCXML_OPT_LIBS} ${USCXML_CORE_LIBS}) endif() diff --git a/contrib/build-scripts/build-v8-linux.sh b/contrib/build-scripts/build-v8-linux.sh index 256a5c6..07aac94 100755 --- a/contrib/build-scripts/build-v8-linux.sh +++ b/contrib/build-scripts/build-v8-linux.sh @@ -14,6 +14,14 @@ PLATFORM_ID=`${DIR}/platform-id-linux.sh` DEST_DIR="${DIR}/../prebuilt/${PLATFORM_ID}" PWD=`pwd` +if [ "${CPUARCH}" = "i686" ]; then + echo + echo "v8 will no longer compile on 32bit" + echo "Start from a 64bit host and we will cross-compile" + echo + exit +fi + if [ ! -f src/v8.h ]; then echo echo "Cannot find src/v8.h" @@ -31,29 +39,94 @@ if [ ! -f ../depot_tools/update_depot_tools ]; then exit fi +# export CXX="`which clang++` -fPIC" +export CFLAGS="-fPIC" +export CXXFLAGS="-fPIC" +export GYPFLAGS="-Dv8_use_external_startup_data=0" + DEPOT_PATH="${PWD}/../depot_tools" export PATH="${DEPOT_PATH}:${PATH}" -if [ "${CPUARCH}" = "x86_64" ]; then - make x64.debug - make x64.release - - cp ./out/x64.debug/obj.target/tools/gyp/libv8_base.x64.a ${DEST_DIR}/lib/libv8_base_d.a - cp ./out/x64.debug/obj.target/tools/gyp/libv8_snapshot.a ${DEST_DIR}/lib/libv8_snapshot_d.a - cp ./out/x64.release/obj.target/tools/gyp/libv8_base.x64.a ${DEST_DIR}/lib/libv8_base.a - cp ./out/x64.release/obj.target/tools/gyp/libv8_snapshot.a ${DEST_DIR}/lib/libv8_snapshot.a - -fi +PLATFORM_ID=`${DIR}/platform-id-linux.sh x86_64` +DEST_DIR="${DIR}/../prebuilt/${PLATFORM_ID}" -if [ "${CPUARCH}" = "i686" ]; then - make ia32.debug - make ia32.release - - cp ./out/ia32.debug/obj.target/tools/gyp/libv8_base.ia32.a ${DEST_DIR}/lib/libv8_base_d.a - cp ./out/ia32.debug/obj.target/tools/gyp/libv8_snapshot.a ${DEST_DIR}/lib/libv8_snapshot_d.a - cp ./out/ia32.release/obj.target/tools/gyp/libv8_base.ia32.a ${DEST_DIR}/lib/libv8_base.a - cp ./out/ia32.release/obj.target/tools/gyp/libv8_snapshot.a ${DEST_DIR}/lib/libv8_snapshot.a - -fi +cp include/*.h ${DEST_DIR}/include + +make V=1 x64.debug +make V=1 x64.release + +# libv8_external_snapshot.a +# libv8_libplatform.a +# libv8_base.a +# libv8_libbase.a +# libv8_nosnapshot.a + + +cp ./out/x64.debug/obj.target/tools/gyp/libv8_external_snapshot.a ${DEST_DIR}/lib/libv8_external_snapshot_d.a +cp ./out/x64.debug/obj.target/tools/gyp/libv8_libplatform.a ${DEST_DIR}/lib/libv8_libplatform_d.a +cp ./out/x64.debug/obj.target/tools/gyp/libv8_base.a ${DEST_DIR}/lib/libv8_base_d.a +cp ./out/x64.debug/obj.target/tools/gyp/libv8_libbase.a ${DEST_DIR}/lib/libv8_libbase_d.a +cp ./out/x64.debug/obj.target/tools/gyp/libv8_nosnapshot.a ${DEST_DIR}/lib/libv8_nosnapshot_d.a +cp ./out/x64.debug/obj.target/third_party/icu/libicuuc.a ${DEST_DIR}/lib/libicuuc_d.a +cp ./out/x64.debug/obj.target/third_party/icu/libicui18n.a ${DEST_DIR}/lib/libicui18n_d.a +cp ./out/x64.debug/obj.target/third_party/icu/libicudata.a ${DEST_DIR}/lib/libicudata_d.a -cp include/* ${DEST_DIR}/include + +cp ./out/x64.release/obj.target/tools/gyp/libv8_external_snapshot.a ${DEST_DIR}/lib/libv8_external_snapshot.a +cp ./out/x64.release/obj.target/tools/gyp/libv8_libplatform.a ${DEST_DIR}/lib/libv8_libplatform.a +cp ./out/x64.release/obj.target/tools/gyp/libv8_base.a ${DEST_DIR}/lib/libv8_base.a +cp ./out/x64.release/obj.target/tools/gyp/libv8_libbase.a ${DEST_DIR}/lib/libv8_libbase.a +cp ./out/x64.release/obj.target/tools/gyp/libv8_nosnapshot.a ${DEST_DIR}/lib/libv8_nosnapshot.a +cp ./out/x64.release/obj.target/third_party/icu/libicuuc.a ${DEST_DIR}/lib/libicuuc.a +cp ./out/x64.release/obj.target/third_party/icu/libicui18n.a ${DEST_DIR}/lib/libicui18n.a +cp ./out/x64.release/obj.target/third_party/icu/libicudata.a ${DEST_DIR}/lib/libicudata.a + + +PLATFORM_ID=`${DIR}/platform-id-linux.sh i686` +DEST_DIR="${DIR}/../prebuilt/${PLATFORM_ID}" + +cp include/*.h ${DEST_DIR}/include + +make V=1 ia32.debug +make V=1 ia32.release + +cp ./out/ia32.debug/obj.target/tools/gyp/libv8_external_snapshot.a ${DEST_DIR}/lib/libv8_external_snapshot_d.a +cp ./out/ia32.debug/obj.target/tools/gyp/libv8_libplatform.a ${DEST_DIR}/lib/libv8_libplatform_d.a +cp ./out/ia32.debug/obj.target/tools/gyp/libv8_base.a ${DEST_DIR}/lib/libv8_base_d.a +cp ./out/ia32.debug/obj.target/tools/gyp/libv8_libbase.a ${DEST_DIR}/lib/libv8_libbase_d.a +cp ./out/ia32.debug/obj.target/tools/gyp/libv8_nosnapshot.a ${DEST_DIR}/lib/libv8_nosnapshot_d.a +cp ./out/ia32.debug/obj.target/third_party/icu/libicuuc.a ${DEST_DIR}/lib/libicuuc_d.a +cp ./out/ia32.debug/obj.target/third_party/icu/libicui18n.a ${DEST_DIR}/lib/libicui18n_d.a +cp ./out/ia32.debug/obj.target/third_party/icu/libicudata.a ${DEST_DIR}/lib/libicudata_d.a + +cp ./out/ia32.release/obj.target/tools/gyp/libv8_external_snapshot.a ${DEST_DIR}/lib/libv8_external_snapshot.a +cp ./out/ia32.release/obj.target/tools/gyp/libv8_libplatform.a ${DEST_DIR}/lib/libv8_libplatform.a +cp ./out/ia32.release/obj.target/tools/gyp/libv8_base.a ${DEST_DIR}/lib/libv8_base.a +cp ./out/ia32.release/obj.target/tools/gyp/libv8_libbase.a ${DEST_DIR}/lib/libv8_libbase.a +cp ./out/ia32.release/obj.target/tools/gyp/libv8_nosnapshot.a ${DEST_DIR}/lib/libv8_nosnapshot.a +cp ./out/ia32.release/obj.target/third_party/icu/libicuuc.a ${DEST_DIR}/lib/libicuuc.a +cp ./out/ia32.release/obj.target/third_party/icu/libicui18n.a ${DEST_DIR}/lib/libicui18n.a +cp ./out/ia32.release/obj.target/third_party/icu/libicudata.a ${DEST_DIR}/lib/libicudata.a + +# if [ "${CPUARCH}" = "x86_64" ]; then +# make x64.debug +# make x64.release +# +# # cp ./out/x64.debug/obj.target/tools/gyp/libv8_base.x64.a ${DEST_DIR}/lib/libv8_base_d.a +# # cp ./out/x64.debug/obj.target/tools/gyp/libv8_snapshot.a ${DEST_DIR}/lib/libv8_snapshot_d.a +# # cp ./out/x64.release/obj.target/tools/gyp/libv8_base.x64.a ${DEST_DIR}/lib/libv8_base.a +# # cp ./out/x64.release/obj.target/tools/gyp/libv8_snapshot.a ${DEST_DIR}/lib/libv8_snapshot.a +# +# fi +# +# if [ "${CPUARCH}" = "i686" ]; then +# make ia32.debug +# make ia32.release +# +# # cp ./out/ia32.debug/obj.target/tools/gyp/libv8_base.ia32.a ${DEST_DIR}/lib/libv8_base_d.a +# # cp ./out/ia32.debug/obj.target/tools/gyp/libv8_snapshot.a ${DEST_DIR}/lib/libv8_snapshot_d.a +# # cp ./out/ia32.release/obj.target/tools/gyp/libv8_base.ia32.a ${DEST_DIR}/lib/libv8_base.a +# # cp ./out/ia32.release/obj.target/tools/gyp/libv8_snapshot.a ${DEST_DIR}/lib/libv8_snapshot.a +# +# fi +# diff --git a/contrib/build-scripts/build-v8-macosx.sh b/contrib/build-scripts/build-v8-macosx.sh index 9396251..1992324 100755 --- a/contrib/build-scripts/build-v8-macosx.sh +++ b/contrib/build-scripts/build-v8-macosx.sh @@ -6,7 +6,7 @@ # # exit on error -set -e +# set -e ME=`basename $0` DIR="$( cd "$( dirname "$0" )" && pwd )" @@ -16,7 +16,6 @@ PLATFORM_ID=`${DIR}/platform-id-mac.sh` DEST_DIR="${DIR}/../prebuilt/${PLATFORM_ID}" PWD=`pwd` -export MACOSX_DEPLOYMENT_TARGET=10.6 if [ ! -f src/v8.h ]; then echo @@ -39,41 +38,100 @@ DEPOT_PATH="${PWD}/../depot_tools" export PATH="${DEPOT_PATH}:${PATH}" if [ ${MACOSX_COMP[1]} -lt 9 ]; then - CXXFLAGS="-mmacosx-version-min=10.6 -stdlib=libstdc++" - LDFLAGS="-stdlib=libstdc++" + export MACOSX_DEPLOYMENT_TARGET=10.6 + export GYP_DEFINES="clang=1 mac_deployment_target=10.6" + export CXX="`which clang++` -mmacosx-version-min=10.6 -stdlib=libstdc++" + export LINK="`which clang++` -stdlib=libstdc++" + # export CXXFLAGS="-mmacosx-version-min=10.6 -stdlib=libstdc++" + # export LDFLAGS="-stdlib=libstdc++" else - CXXFLAGS="-mmacosx-version-min=10.7 -stdlib=libc++" - LDFLAGS="-stdlib=libc++" + export MACOSX_DEPLOYMENT_TARGET=10.7 + export GYP_DEFINES="clang=1 mac_deployment_target=10.7" + export CXX="`which clang++` -mmacosx-version-min=10.7 -stdlib=libc++" + export LINK="`which clang++` -stdlib=libc++" + # export CXXFLAGS="-mmacosx-version-min=10.7 -stdlib=libc++" + # export LDFLAGS="-stdlib=libc++" fi -make dependencies +# make dependencies -make ia32.release -make ia32.debug +make snapshot=off ia32.release +make snapshot=off ia32.debug -make x64.release -make x64.debug +make snapshot=off x64.release +make snapshot=off x64.debug -cp include/* ${DEST_DIR}/include +cp include/*.h ${DEST_DIR}/include +#release lipo -create \ - ./out/x64.release/libv8_base.x64.a \ - ./out/ia32.release/libv8_base.ia32.a \ + ./out/x64.release/libv8_base.a \ + ./out/ia32.release/libv8_base.a \ -output ${DEST_DIR}/lib/libv8_base.a - + lipo -create \ - ./out/x64.release/libv8_snapshot.a \ - ./out/ia32.release/libv8_snapshot.a \ - -output ${DEST_DIR}/lib/libv8_snapshot.a - + ./out/x64.release/libv8_libbase.a \ + ./out/ia32.release/libv8_libbase.a \ + -output ${DEST_DIR}/lib/libv8_libbase.a + lipo -create \ - ./out/x64.debug/libv8_base.x64.a \ - ./out/ia32.debug/libv8_base.ia32.a \ + ./out/x64.release/libv8_libplatform.a \ + ./out/ia32.release/libv8_libplatform.a \ + -output ${DEST_DIR}/lib/libv8_libplatform.a + +lipo -create \ + ./out/x64.release/libv8_external_snapshot.a \ + ./out/ia32.release/libv8_external_snapshot.a \ + -output ${DEST_DIR}/lib/libv8_external_snapshot.a + +lipo -create \ + ./out/x64.release/libicuuc.a \ + ./out/ia32.release/libicuuc.a \ + -output ${DEST_DIR}/lib/libicuuc.a + +lipo -create \ + ./out/x64.release/libicui18n.a \ + ./out/ia32.release/libicui18n.a \ + -output ${DEST_DIR}/lib/libicui18n.a + +lipo -create \ + ./out/x64.release/libicudata.a \ + ./out/ia32.release/libicudata.a \ + -output ${DEST_DIR}/lib/libicudata.a + +#debug +lipo -create \ + ./out/x64.debug/libv8_base.a \ + ./out/ia32.debug/libv8_base.a \ -output ${DEST_DIR}/lib/libv8_base_d.a lipo -create \ - ./out/x64.debug/libv8_snapshot.a \ - ./out/ia32.debug/libv8_snapshot.a \ - -output ${DEST_DIR}/lib/libv8_snapshot_d.a - + ./out/x64.debug/libv8_libbase.a \ + ./out/ia32.debug/libv8_libbase.a \ + -output ${DEST_DIR}/lib/libv8_libbase_d.a + +lipo -create \ + ./out/x64.debug/libv8_libplatform.a \ + ./out/ia32.debug/libv8_libplatform.a \ + -output ${DEST_DIR}/lib/libv8_libplatform_d.a + +lipo -create \ + ./out/x64.debug/libv8_external_snapshot.a \ + ./out/ia32.debug/libv8_external_snapshot.a \ + -output ${DEST_DIR}/lib/libv8_external_snapshot_d.a + +lipo -create \ + ./out/x64.debug/libicuuc.a \ + ./out/ia32.debug/libicuuc.a \ + -output ${DEST_DIR}/lib/libicuuc_d.a + +lipo -create \ + ./out/x64.debug/libicui18n.a \ + ./out/ia32.debug/libicui18n.a \ + -output ${DEST_DIR}/lib/libicui18n_d.a + +lipo -create \ + ./out/x64.debug/libicudata.a \ + ./out/ia32.debug/libicudata.a \ + -output ${DEST_DIR}/lib/libicudata_d.a diff --git a/contrib/build-scripts/build-v8-windows.bat b/contrib/build-scripts/build-v8-windows.bat new file mode 100644 index 0000000..21e33dc --- /dev/null +++ b/contrib/build-scripts/build-v8-windows.bat @@ -0,0 +1,87 @@ +@ECHO off + +set ME=%0 +set DIR=%~dp0 +set MSVC_VER="" +set DEPOT_TOOLS_WIN_TOOLCHAIN=0 + +if "%VSINSTALLDIR%" == "" ( + echo. + echo %VSINSTALLDIR is not defined, run from within Visual Studio Command Prompt. + echo. + goto :DONE +) + +cl.exe 2>&1 |findstr "Version\ 19.00" > nul +if %errorlevel% == 0 ( + set MSVC_VER=1900 + set GYP_MSVS_VERSION=2015 +) + +cl.exe 2>&1 |findstr "Version\ 18.00" > nul +if %errorlevel% == 0 ( + set MSVC_VER=1800 + set GYP_MSVS_VERSION=2013 +) + +cl.exe 2>&1 |findstr "Version\ 16.00" > nul +if %errorlevel% == 0 ( + set MSVC_VER=1600 + set GYP_MSVS_VERSION=2010 +) + +if [%MSVC_VER%] == [""] ( + echo. + echo Unknown MSVC_VER %MSVC_VER%. + echo. + goto :DONE +) + +echo %LIB% |find "LIB\amd64;" > nul +if %errorlevel% == 0 ( + set DEST_DIR="%DIR%..\prebuilt\windows-x86_64-msvc%MSVC_VER%" + set CPU_ARCH=x86_64 + goto :ARCH_FOUND +) + +echo %LIB% |find "LIB;" > nul +if %errorlevel% == 0 ( + set DEST_DIR="%DIR%..\prebuilt\windows-x86-msvc%MSVC_VER%" + set CPU_ARCH=x86 + goto :ARCH_FOUND +) + +:ARCH_FOUND + +if "%DEST_DIR%" == "" ( + echo. + echo Unknown Platform %Platform%. + echo. + goto :DONE +) + +IF NOT EXIST "src/v8.h" ( + echo. + echo Cannot find src/v8.h + echo Run script from within v8 directory: + echo v8 $ %ME% + echo. + goto :DONE +) + +echo. +echo Building with MCVC ver %MSVC_VER% for %CPU_ARCH% into %DEST_DIR% +echo. + +if "%CPU_ARCH%" == "x86_64" ( + python build\gyp_v8 -Dtarget_arch=x64 + devenv /build Release build\All.sln + +) + +if "%CPU_ARCH%" == "x86" ( + python build\gyp_v8 +) + +:DONE +pause \ No newline at end of file diff --git a/contrib/build-scripts/platform-id-linux.sh b/contrib/build-scripts/platform-id-linux.sh index 9efac91..b0e4688 100755 --- a/contrib/build-scripts/platform-id-linux.sh +++ b/contrib/build-scripts/platform-id-linux.sh @@ -9,4 +9,8 @@ CMAKE_INFO=`cmake --system-information 2> /dev/null` CMAKE_CXX_COMPILER_ID=`echo "$CMAKE_INFO" |grep 'CMAKE_CXX_COMPILER_ID ' | awk '{print tolower($2)}' |sed 's/\"//g'` CPU=`uname -m` +if (( $# > 0 )); then + CPU=$1 +fi + echo "linux-${CPU}-${CMAKE_CXX_COMPILER_ID}" diff --git a/contrib/dom/scripts/CodeGeneratorArabicaV8-pre3.14.pm b/contrib/dom/scripts/CodeGeneratorArabicaV8-pre3.14.pm deleted file mode 100644 index 0095f6b..0000000 --- a/contrib/dom/scripts/CodeGeneratorArabicaV8-pre3.14.pm +++ /dev/null @@ -1,1023 +0,0 @@ -# Copyright (C) 2005, 2006 Nikolas Zimmermann -# Copyright (C) 2006 Anders Carlsson -# Copyright (C) 2006 Samuel Weinig -# Copyright (C) 2006 Alexey Proskuryakov -# Copyright (C) 2006 Apple Computer, Inc. -# Copyright (C) 2007, 2008, 2009, 2012 Google Inc. -# Copyright (C) 2009 Cameron McCormack -# Copyright (C) Research In Motion Limited 2010. All rights reserved. -# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) -# Copyright (C) 2012 Ericsson AB. All rights reserved. -# Copyright (C) 2013 Stefan Radomski -# -# 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. -# - -package CodeGeneratorArabicaV8; - -use strict; -use Data::Dumper; -use Carp qw/longmess cluck confess/; - -use constant FileNamePrefix => "V8"; - -my $codeGenerator; - - -my @headerContent = (); -my @implContentHeader = (); -my @implContent = (); -my @implContentDecls = (); -my %implIncludes = (); -my %headerIncludes = (); - -# Default .h template -my $headerTemplate = << 'EOF'; -/** - * @file - * @author This file has been generated by generate-bindings.pl. DO NOT MODIFY! - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program 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. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see . - * @endcond - */ - -EOF - -# Default constructor -sub new -{ - my $object = shift; - my $reference = { }; - - $codeGenerator = shift; - - bless($reference, $object); - return $reference; -} - -sub GenerateInterface -{ - my $object = shift; - my $interface = shift; - -# print Dumper($interface); - - # Start actual generation - if ($interface->extendedAttributes->{"Callback"}) { - die(); - $object->GenerateCallbackHeader($interface); - $object->GenerateCallbackImplementation($interface); - } else { - $object->GenerateHeader($interface); - $object->GenerateImplementation($interface); - } -} - -sub AddToImplIncludes -{ - my $header = shift; - my $conditional = shift; - - if ($header eq "V8bool.h") { - confess(); - } - - if (not $conditional) { - $implIncludes{$header} = 1; - } elsif (not exists($implIncludes{$header})) { - $implIncludes{$header} = $conditional; - } else { - my $oldValue = $implIncludes{$header}; - if ($oldValue ne 1) { - my %newValue = (); - $newValue{$conditional} = 1; - foreach my $condition (split(/\|/, $oldValue)) { - $newValue{$condition} = 1; - } - $implIncludes{$header} = join("|", sort keys %newValue); - } - } -} - -sub GenerateHeader -{ - my $object = shift; - my $interface = shift; - my $interfaceName = $interface->name; - my $extensions = $interface->extendedAttributes; -# print Dumper($extensions); - - # Copy contents of parent interfaces except the first parent. - my @parents; - $codeGenerator->AddMethodsConstantsAndAttributesFromParentInterfaces($interface, \@parents, 1); - $codeGenerator->LinkOverloadedFunctions($interface); - - # - Add default header template - push(@headerContent, GenerateHeaderContentHeader($interface)); - - $headerIncludes{"string"} = 1; - $headerIncludes{"uscxml/plugins/datamodel/ecmascript/v8/V8DOM.h"} = 1; - $headerIncludes{"DOM/Node.hpp"} = 1; - $headerIncludes{"v8.h"} = 1; - - if ($interfaceName =~ /.*Array$/ or $interfaceName =~ /^ArrayBuffer.*/) { - $headerIncludes{"../../TypedArray.h"} = 1; - } - - foreach (@{$interface->parents}) { - my $parent = $_; - $headerIncludes{"V8${parent}.h"} = 1; - } - - push(@headerContent, "#include \\n"); - foreach my $headerInclude (sort keys(%headerIncludes)) { - if ($headerInclude =~ /wtf|v8\.h/) { - push(@headerContent, "#include \<${headerInclude}\>\n"); - } else { - push(@headerContent, "#include \"${headerInclude}\"\n"); - } - } - - push(@headerContent, ""); - push(@headerContent, "\nnamespace Arabica {"); - push(@headerContent, "\nnamespace DOM {\n"); - - push(@headerContent, "\nclass V8${interfaceName} {"); - push(@headerContent, "\npublic:"); - - my $wrapperType = IdlToWrapperType($interfaceName); - push(@headerContent, <{'DontDestroyWrapped'}) { - push(@headerContent, "\n V8_DESTRUCTOR_KEEP_WRAPPED(V8${interfaceName}Private);"); - } else { - push(@headerContent, "\n V8_DESTRUCTOR(V8${interfaceName}Private);"); - } - push(@headerContent, "\n static bool hasInstance(v8::Handle);"); - push(@headerContent, "\n"); - - # callbacks for actual functions - my %generated; - foreach my $function (@{$interface->functions}) { - my $name = $function->signature->name; - my $attrExt = $function->signature->extendedAttributes; - my $custom = ($attrExt->{'Custom'} ? "Custom" : ""); - next if (exists $generated{"${name}${custom}Callback"}); - push(@headerContent, "\n static v8::Handle ${name}${custom}Callback(const v8::Arguments&);"); - $generated{"${name}${custom}Callback"} = 1; - } - push(@headerContent, "\n"); - - # attribute getter and setters - foreach my $attribute (@{$interface->attributes}) { - my $name = $attribute->signature->name; - my $attrExt = $attribute->signature->extendedAttributes; - my $customGetter = ($attrExt->{'CustomGetter'} ? "Custom" : ""); - my $customSetter = ($attrExt->{'CustomSetter'} ? "Custom" : ""); - push(@headerContent, "\n static v8::Handle ${name}${customGetter}AttrGetter(v8::Local property, const v8::AccessorInfo& info);"); - if (!IsReadonly($attribute)) { - push(@headerContent, "\n static void ${name}${customSetter}AttrSetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info);"); - } - } - - if ($extensions->{'CustomIndexedGetter'}) { - push(@headerContent, "\n static v8::Handle indexedPropertyCustomGetter(uint32_t, const v8::AccessorInfo&);"); - } - if ($extensions->{'CustomIndexedSetter'}) { - push(@headerContent, "\n static v8::Handle indexedPropertyCustomSetter(uint32_t, v8::Local, const v8::AccessorInfo&);"); - } - push(@headerContent, "\n"); - - GenerateClassPrototypeHeader($interface); - - push(@headerContent, "\n};\n\n}\n}\n\n"); - push(@headerContent, "#endif // V8${interfaceName}" . "_h\n"); - -} - -# -# Write class template prototype constructor -# -sub GenerateClassPrototypeHeader -{ - my $interface = shift; - my $interfaceName = $interface->name; - my $extensions = $interface->extendedAttributes; - - if ($extensions->{'Constructors'}) { - - push(@headerContent, "\n"); - push(@headerContent, " static v8::Handle constructor(const v8::Arguments&);\n"); - push(@headerContent, " static v8::Persistent Constr;\n"); - push(@headerContent, < getConstructor() { - if (Constr.IsEmpty()) { - v8::Handle constr = v8::FunctionTemplate::New(constructor); - Constr = v8::Persistent::New(constr); - } - return Constr; - } -END - } - - push(@headerContent, "\n static v8::Persistent Tmpl;\n"); - push(@headerContent, < getTmpl() { - if (Tmpl.IsEmpty()) { - v8::Handle tmpl = v8::FunctionTemplate::New(); - tmpl->SetClassName(v8::String::New("${interfaceName}")); - tmpl->ReadOnlyPrototype(); - - v8::Local instance = tmpl->InstanceTemplate(); - v8::Local prototype = tmpl->PrototypeTemplate(); - (void)prototype; // surpress unused warnings - - instance->SetInternalFieldCount(1); -END - - push(@headerContent, "\n"); - foreach my $attribute (@{$interface->attributes}) { - my $name = $attribute->signature->name; - my $attrExt = $attribute->signature->extendedAttributes; - my $customGetter = ($attrExt->{'CustomGetter'} ? "Custom" : ""); - my $customSetter = ($attrExt->{'CustomSetter'} ? "Custom" : ""); - my $getter = "V8${interfaceName}::${name}${customGetter}AttrGetter"; - my $setter = (IsReadonly($attribute) ? "0" : "V8${interfaceName}::${name}${customSetter}AttrSetter"); - push(@headerContent, <SetAccessor(v8::String::NewSymbol("${name}"), ${getter}, ${setter}, - v8::External::New(0), static_cast(v8::DEFAULT), static_cast(v8::None)); -END - } - - if ($extensions->{'CustomIndexedGetter'} || $extensions->{'CustomIndexedSetter'}) { - my $indexedGetter = ($extensions->{'CustomIndexedGetter'} ? "V8${interfaceName}::indexedPropertyCustomGetter" : 0); - my $indexedSetter = ($extensions->{'CustomIndexedSetter'} ? "V8${interfaceName}::indexedPropertyCustomSetter" : 0); - push(@headerContent, "\n instance->SetIndexedPropertyHandler(${indexedGetter}, ${indexedSetter});"); - } - - push(@headerContent, "\n"); - my %generated; - foreach my $function (@{$interface->functions}) { - my $name = $function->signature->name; - my $attrExt = $function->signature->extendedAttributes; - my $custom = ($attrExt->{'Custom'} ? "Custom" : ""); - next if (exists $generated{"${name}"}); - $generated{"${name}"} = 1; - push(@headerContent, <Set(v8::String::NewSymbol("${name}"), - v8::FunctionTemplate::New(V8${interfaceName}::${name}${custom}Callback, v8::Undefined()), static_cast(v8::DontDelete)); -END - } - - push(@headerContent, "\n"); - foreach my $constant (@{$interface->constants}) { - my $name = $constant->name; - my $value = $constant->value; - my $type = IdlToV8Type($constant->type); - push(@headerContent, <Set(v8::String::NewSymbol("${name}"), ${type}::New(${value}), static_cast(v8::ReadOnly | v8::DontEnum)); - prototype->Set(v8::String::NewSymbol("${name}"), ${type}::New(${value}), static_cast(v8::ReadOnly | v8::DontEnum)); -END - } - - push(@headerContent, "\n"); - if (@{$interface->parents}) { - my $parent = @{$interface->parents}[0]; - push(@headerContent, " tmpl->Inherit(V8${parent}::getTmpl());\n"); - } - push(@headerContent, <::New(tmpl); - } - return Tmpl; - } - -END - -} - -sub GenerateImplementationAttributes -{ - my $interface = shift; - my $interfaceName = $interface->name; - my $extensions = $interface->extendedAttributes; - - # Generate property accessors for attributes. - for (my $index = 0; $index < @{$interface->attributes}; $index++) { - my $attribute = @{$interface->attributes}[$index]; - my $attrType = $attribute->signature->type; - my $attrName = $attribute->signature->name; - my $attrExt = $attribute->signature->extendedAttributes; - - my $wrapperRetType = IdlToWrapperType($attrType); - my $wrapperType = IdlToWrapperType($interfaceName); - my $wrapperGetter; - - if ($attrExt->{'AttributeIsPublic'} || $extensions->{'AttributesArePublic'}) { - $wrapperGetter = $attrName; - } else { - $wrapperGetter = IdlToWrapperAttrGetter($interface, $attribute)."()"; - - } - - # getter - if (!$attrExt->{'CustomGetter'}) { - push(@implContent, < V8${interfaceName}::${attrName}AttrGetter(v8::Local property, const v8::AccessorInfo& info) { - v8::Local self = info.Holder(); - struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0)); -END - if (IsWrapperType($attrType)) { - AddToImplIncludes("V8".$attrType.".h"); - push(@implContent, "\n ".GenerateConditionalUndefReturn($interface, $attribute, "privData->nativeObj->${wrapperGetter}")); - - push(@implContent, <nativeObj->${wrapperGetter}); - - v8::Handle arbaicaRetCtor = V8${attrType}::getTmpl()->GetFunction(); - v8::Persistent arbaicaRetObj = v8::Persistent::New(arbaicaRetCtor->NewInstance()); - - struct V8${attrType}::V8${attrType}Private* retPrivData = new V8${attrType}::V8${attrType}Private(); - retPrivData->dom = privData->dom; - retPrivData->nativeObj = arbaicaRet; - - arbaicaRetObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - arbaicaRetObj.MakeWeak(0, V8${attrType}::jsDestructor); - return arbaicaRetObj; -END - } else { - my $v8Type = IdlToV8Type($attrType); - if ($attrType eq "DOMString") { - if ($attrExt->{'EmptyAsNull'}) { - push(@implContent, "\n if (privData->nativeObj->${wrapperGetter}.length() == 0)"); - push(@implContent, "\n return v8::Undefined();"); - } - push(@implContent, "\n return ${v8Type}::New(privData->nativeObj->${wrapperGetter}.c_str());"); - } else { - push(@implContent, "\n return ${v8Type}::New(privData->nativeObj->${wrapperGetter});"); - } - } - push(@implContent, "\n }\n"); - } - - if (!$attrExt->{'CustomSetter'}) { - # setter - if (!IsReadonly($attribute)) { - my $wrapperSetter = IdlToWrapperAttrSetter($attrName); - push(@implContent, "\n void V8${interfaceName}::${attrName}AttrSetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info) {"); - push(@implContent, "\n v8::Local self = info.Holder();"); - push(@implContent, "\n struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0));"); - - my ($handle, $deref) = IdlToArgHandle($attribute->signature->type, "local".ucfirst($attribute->signature->name), "value", $interfaceName); - - push(@implContent, "\n $handle"); - push(@implContent, "\n privData->nativeObj->${wrapperSetter}(${deref});"); - push(@implContent, "\n }\n"); - - } - } - } -} - -sub GenerateConditionalUndefReturn -{ - my $interface = shift; - my $attribute = shift; - my $getterExpression = shift; - - return "" if ($attribute->signature->type eq "NamedNodeMap"); - return "" if ($attribute->signature->type eq "NodeList"); - return "if (!$getterExpression) return v8::Undefined();"; -} - -sub GenerateConstructor -{ - my $interface = shift; - my $interfaceName = $interface->name; - my $wrapperType = IdlToWrapperType($interfaceName); - my $extensions = $interface->extendedAttributes; - - if ($extensions->{'Constructors'}) { - - push(@implContent, "\n v8::Handle V8${interfaceName}::constructor(const v8::Arguments& args) {"); - push(@implContent, <{'Constructors'}}) { - push (@variants, $fullCons); - - for (my $i = @{$fullCons}; $i > 0; $i--) { - my $variant = @{$fullCons}[$i]; - if ($variant->{'domSignature::isOptional'}) { - my $slice; - for (my $j = 0; $j < $i; $j++) { - push(@{$slice}, @{$fullCons}[$j]); - } - push (@variants, $slice); - } - } - - # sort to put most determinate signatures first - @variants = sort { - if (@{$b} != @{$a}) { - # more arguments are more determinant - @{$b} <=> @{$a}; - } else { - my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a}); - my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b}); - @bWrap <=> @aWrap; - } - } @variants; - } - foreach my $constructor (@variants) { - push(@implContent, " else if (args.Length() == " . @{$constructor}); - - for (my $i = 0; $i < @{$constructor}; $i++) { - my $type = $constructor->[$i]->{'domSignature::type'}; - AddToImplIncludes("V8".$type.".h") if (IsWrapperType($type)); - push(@implContent, " &&\n " . IdlToTypeChecker($type, "args[$i]")); - - } - push(@implContent, ") {\n"); - my $constructorArgs; - my $constructorSep = ""; - for (my $i = 0; $i < @{$constructor}; $i++) { - my $type = $constructor->[$i]->{'domSignature::type'}; - my $name = $constructor->[$i]->{'domSignature::name'}; - my ($handle, $deref) = IdlToArgHandle($type, "local".ucfirst($name), "args[$i]", $interfaceName); - $constructorArgs .= ${constructorSep}.${deref}; - $constructorSep = ", "; - push(@implContent, "\n $handle"); - - } - push(@implContent, "\n localInstance = new ".IdlToWrapperType($interfaceName)."(${constructorArgs});"); - push(@implContent, "\n\n }"); - } - push(@implContent, "\n"); - - push(@implContent, < retCtor = V8${interfaceName}::getTmpl()->GetFunction(); - v8::Persistent retObj = v8::Persistent::New(retCtor->NewInstance()); - - struct V8${interfaceName}::V8${interfaceName}Private* retPrivData = new V8${interfaceName}::V8${interfaceName}Private(); - retPrivData->nativeObj = localInstance; - - retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - - retObj.MakeWeak(0, V8${interfaceName}::jsDestructor); - return retObj; - } -END - } - -} - -sub GenerateImplementationFunctionCallbacks -{ - my $interface = shift; - my $interfaceName = $interface->name; - my $wrapperType = IdlToWrapperType($interfaceName); - my $extensions = $interface->extendedAttributes; - - - # Generate methods for functions. - my %generated; - foreach my $function (@{$interface->functions}) { - my $name = $function->signature->name; - my $attrExt = $function->signature->extendedAttributes; - my $retType = $function->signature->type; - my $wrapperRetType = IdlToWrapperType($retType); - - next if ($attrExt->{'Custom'}); - next if (exists $generated{"${name}Callback"}); - $generated{"${name}Callback"} = 1; - - # get all functions with this name - my @sameFunctions = grep($_->signature->name eq $name, @{$interface->functions}); - - # signature - push(@implContent, < V8${interfaceName}::${name}Callback(const v8::Arguments& args) { -END - - # get this - push(@implContent, "\n v8::Local self = args.Holder();"); - push(@implContent, "\n struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0));"); - - # establish all variants - my @variants; - foreach my $functionVar (@sameFunctions) { - push (@variants, $functionVar->parameters); - - for (my $i = @{$functionVar->parameters}; $i > 0; $i--) { - my $variant = @{$functionVar->parameters}[$i]; - if ($variant->{'domSignature::isOptional'}) { - my $slice; - for (my $j = 0; $j < $i; $j++) { - push(@{$slice}, @{$functionVar->parameters}[$j]); - } - push (@variants, $slice); - } - } - } - - # arguments to local handles - push(@implContent, "\n if (false) {"); - - # sort to put most determinate signatures first - @variants = sort { - if (@{$b} != @{$a}) { - # more arguments are more determinant - @{$b} <=> @{$a}; - } else { - my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a}); - my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b}); - @bWrap <=> @aWrap; - } - } @variants; - - foreach my $variant (@variants) { - my $parameterIndex = 0; - my @argList; - - push(@implContent, "\n } else if (args.Length() == " . @{$variant}); - for (my $i = 0; $i < @{$variant}; $i++) { - my $type = $variant->[$i]->{'domSignature::type'}; - push(@implContent, " &&\n " . IdlToTypeChecker($type, "args[$i]")); - } - push(@implContent, ")\n {"); - foreach my $parameter (@{$variant}) { - my $value = "args[$parameterIndex]"; - my $type = $parameter->type; - AddToImplIncludes("V8".$type.".h") if (IsWrapperType($type)); - - my ($handle, $deref) = IdlToArgHandle($parameter->type, "local".ucfirst($parameter->name), "args[${parameterIndex}]", $interfaceName); - push(@implContent, "\n ${handle}"); - push(@argList, $deref); - $parameterIndex++; - } - - # invoke native function with argument handles - my $retNativeType = IdlToNativeType($retType); - my $wrapperFunctionName = IdlToWrapperFunction($interface, $function); - if (IsWrapperType($retType)) { - push(@implContent, "\n\n ${retNativeType}* retVal = new $wrapperRetType(privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . "));\n"); - } elsif ($retNativeType eq "void") { - push(@implContent, "\n\n privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n"); - } else { - push(@implContent, "\n\n ${retNativeType} retVal = privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n"); - } - - # wrap return type if needed - if (IsWrapperType($retType)) { - AddToImplIncludes("V8".$retType.".h"); - - push(@implContent, < retCtor = V8${retType}::getTmpl()->GetFunction(); - v8::Persistent retObj = v8::Persistent::New(retCtor->NewInstance()); - - struct V8${retType}::V8${retType}Private* retPrivData = new V8${retType}::V8${retType}Private(); - retPrivData->dom = privData->dom; - retPrivData->nativeObj = retVal; - - retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - - retObj.MakeWeak(0, V8${retType}::jsDestructor); - return retObj; -END - } else { - my $toHandleString = NativeToHandle($retNativeType, "retVal"); - push(@implContent, "\n return ${toHandleString};"); - } - } - push(@implContent, <name; - my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface); - my $v8InterfaceName = "V8$interfaceName"; - my $wrapperType = IdlToWrapperType($interfaceName); - my $extensions = $interface->extendedAttributes; - - AddToImplIncludes("V8${interfaceName}.h"); - - # Find the super descriptor. - my $parentClass = ""; - my $parentClassTemplate = ""; - foreach (@{$interface->parents}) { - my $parent = $_; - AddToImplIncludes("V8${parent}.h"); - $parentClass = "V8" . $parent; - last; - } - - push(@implContent, "namespace Arabica {\n"); - push(@implContent, "namespace DOM {\n\n"); - push(@implContent, " v8::Persistent V8${interfaceName}::Tmpl;\n"); - - if ($extensions->{'Constructors'}) { - push(@implContent, " v8::Persistent V8${interfaceName}::Constr;\n"); - GenerateConstructor($interface); - } - - GenerateImplementationAttributes($interface); - GenerateImplementationFunctionCallbacks($interface); - - - push(@implContent, < value) { - return getTmpl()->HasInstance(value); - } - -} -} -END - - # We've already added the header for this file in implContentHeader, so remove - # it from implIncludes to ensure we don't #include it twice. -# delete $implIncludes{"${v8InterfaceName}.h"}; -} - -sub WriteData -{ - my $object = shift; - my $interface = shift; - my $outputDir = shift; - my $outputHeadersDir = shift; - - my $name = $interface->name; - my $prefix = FileNamePrefix; - my $headerFileName = "$outputHeadersDir/$prefix$name.h"; - my $implFileName = "$outputDir/$prefix$name.cpp"; - - # print "WriteData\n"; - # print Dumper($interface); - # exit(); - - # Update a .cpp file if the contents are changed. - my $contents = $headerTemplate; - $contents .= join "", @implContentHeader; - - my @includes = (); - my %implIncludeConditions = (); - foreach my $include (keys %implIncludes) { - my $condition = $implIncludes{$include}; - my $checkType = $include; - $checkType =~ s/\.h//; - next if $codeGenerator->IsSVGAnimatedType($checkType); - - if ($include =~ /wtf/) { - $include = "\<$include\>"; - } else { - $include = "\"$include\""; - } - - if ($condition eq 1) { - push @includes, $include; - } else { - push @{$implIncludeConditions{$condition}}, $include; - } - } - foreach my $include (sort @includes) { - $contents .= "#include $include\n"; - } - foreach my $condition (sort keys %implIncludeConditions) { - $contents .= "\n#if " . $codeGenerator->GenerateConditionalStringFromAttributeValue($condition) . "\n"; - foreach my $include (sort @{$implIncludeConditions{$condition}}) { - $contents .= "#include $include\n"; - } - $contents .= "#endif\n"; - } - - $contents .= "\n"; - $contents .= join "", @implContentDecls, @implContent; - $codeGenerator->UpdateFile($implFileName, $contents); - - %implIncludes = (); - @implContentHeader = (); - @implContentDecls = (); - @implContent = (); - - # Update a .h file if the contents are changed. - $contents = join "", @headerContent; - $codeGenerator->UpdateFile($headerFileName, $contents); - - @headerContent = (); -} - -sub IdlToV8Type -{ - my $idlType = shift; - return "v8::Integer" if ($idlType eq "unsigned short"); - return "v8::Integer" if ($idlType eq "short"); - return "v8::Integer" if ($idlType eq "unsigned long"); - return "v8::Integer" if ($idlType eq "long"); - return "v8::String" if ($idlType eq "DOMString"); - return "v8::Boolean" if ($idlType eq "boolean"); - return "v8::Number" if ($idlType eq "double"); - die($idlType); -} - -sub IdlToNativeType -{ - my $idlType = shift; - - return IdlToWrapperType($idlType) if (IsWrapperType($idlType)); - - return "std::string" if ($idlType eq "DOMString"); - return "bool" if ($idlType eq "boolean"); - return "short" if ($idlType eq "short"); - return "long" if ($idlType eq "long"); - return "unsigned short" if ($idlType eq "unsigned short"); - return "unsigned long" if ($idlType eq "unsigned long"); - return "void" if ($idlType eq "void"); - return "char" if ($idlType eq "byte"); - return "unsigned char" if ($idlType eq "octet"); - return "double" if ($idlType eq "double"); - return "float" if ($idlType eq "float"); - die(${idlType}); -} - -sub NativeToHandle -{ - my $nativeType = shift; - my $nativeName = shift; - - return ("v8::Boolean::New(${nativeName})") if ($nativeType eq "bool"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "double"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "double"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "float"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "short"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "char"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned short"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned long"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned char"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "long"); - return ("v8::String::New(${nativeName}.c_str())") if ($nativeType eq "std::string"); - return ("v8::Undefined()") if ($nativeType eq "void"); - - die($nativeType); -} - -sub IdlToWrapperType -{ - my $idlType = shift; - return "Arabica::XPath::XPathValue" if ($idlType eq "XPathResult"); - return "Arabica::XPath::NodeSet" if ($idlType eq "NodeSet"); - return "Arabica::DOM::Node" if ($idlType eq "Node"); - return "Arabica::DOM::Element" if ($idlType eq "Element"); - return "uscxml::Event" if ($idlType eq "SCXMLEvent"); - return "uscxml::Storage" if ($idlType eq "Storage"); - return "uscxml::ArrayBuffer" if ($idlType eq "ArrayBuffer"); - return "uscxml::ArrayBufferView" if ($idlType eq "ArrayBufferView"); - return "uscxml::Int8Array" if ($idlType eq "Int8Array"); - return "uscxml::Uint8Array" if ($idlType eq "Uint8Array"); - return "uscxml::Uint8ClampedArray" if ($idlType eq "Uint8ClampedArray"); - return "uscxml::Int16Array" if ($idlType eq "Int16Array"); - return "uscxml::Uint16Array" if ($idlType eq "Uint16Array"); - return "uscxml::Int32Array" if ($idlType eq "Int32Array"); - return "uscxml::Uint32Array" if ($idlType eq "Uint32Array"); - return "uscxml::Float32Array" if ($idlType eq "Float32Array"); - return "uscxml::Float64Array" if ($idlType eq "Float64Array"); - return "uscxml::DataView" if ($idlType eq "DataView"); - return "Arabica::DOM::${idlType}"; -} - -sub IdlToArgHandle -{ - my $type = shift; - my $localName = shift; - my $paramName = shift; - my $thisType = shift; - - return ("v8::String::AsciiValue ${localName}(${paramName});", "*${localName}") if ($type eq "DOMString"); - return ("unsigned long ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "unsigned long"); - return ("long ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "long"); - return ("double ${localName} = ${paramName}->ToNumber()->Value();", ${localName}) if ($type eq "double"); - return ("float ${localName} = ${paramName}->ToNumber()->Value();", ${localName}) if ($type eq "float"); - return ("unsigned short ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "unsigned short"); - return ("bool ${localName} = ${paramName}->ToBoolean()->BooleanValue();", ${localName}) if ($type eq "boolean"); - return ("char ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "byte"); - return ("short ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "short"); - return ("unsigned char ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "octet"); - return ("void* ${localName} = v8::External::Unwrap(${paramName}->ToObject()->GetInternalField(0));", ${localName}) if ($type eq "any"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInteger()->Value());\n}", "${localName}") if ($type eq "long[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "float[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "double[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "byte[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "short[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned short[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned long[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "octet[]"); - - if (IsWrapperType($type)) { - my $wrapperType = IdlToWrapperType($type); - if ($type =~ /.*Array$/ or $type =~ /^ArrayBuffer.*/) { - return ("${wrapperType}* ${localName} = V8DOM::toClassPtr(${paramName}->ToObject()->GetInternalField(0))->nativeObj;", "${localName}"); - } - - return ("${wrapperType}* ${localName} = V8DOM::toClassPtr(${paramName}->ToObject()->GetInternalField(0))->nativeObj;", "*${localName}"); - } - - print $type."\n"; - die(); -} - -sub IdlToTypeChecker -{ - my $idlType = shift; - my $attr = shift; - - return $attr."->IsString()" if ($idlType eq "DOMString"); - return $attr."->IsBoolean()" if ($idlType eq "boolean"); - return $attr."->IsInt32()" if ($idlType eq "short"); - return $attr."->IsInt32()" if ($idlType eq "long"); - return $attr."->IsArray()" if ($idlType eq "long[]"); - return $attr."->IsUint32()" if ($idlType eq "unsigned short"); - return $attr."->IsUint32()" if ($idlType eq "unsigned long"); - return $attr."->IsInt32()" if ($idlType eq "byte"); - return $attr."->IsUint32()" if ($idlType eq "octet"); - return $attr."->IsNumber()" if ($idlType eq "double"); - return $attr."->IsArray()" if ($idlType eq "double[]"); - return $attr."->IsNumber()" if ($idlType eq "float"); - return $attr."->IsArray()" if ($idlType eq "float[]"); - return $attr."->IsArray()" if ($idlType eq "short[]"); - return $attr."->IsArray()" if ($idlType eq "unsigned short[]"); - return $attr."->IsArray()" if ($idlType eq "unsigned long[]"); - return $attr."->IsArray()" if ($idlType eq "byte[]"); - return $attr."->IsArray()" if ($idlType eq "octet[]"); - return "true" if ($idlType eq "any"); - - return $attr."->IsObject() && V8".$idlType."::hasInstance(".$attr.")" if (IsWrapperType($idlType)); - - print $idlType."\n"; - die(); - -} - -sub IdlToWrapperAttrGetter -{ - my $interface = shift; - my $attribute = shift; - - return $attribute->signature->name if ($interface->name eq "NodeSet" && $attribute->signature->name eq "size"); - return $attribute->signature->name if ($interface->name eq "NodeSet" && $attribute->signature->name eq "empty"); - return "asString" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "stringValue"); - return "asBool" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "booleanValue"); - return "asNumber" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "numberValue"); - - return "get" . ucfirst($attribute->signature->name); -} - -sub IdlToWrapperFunction -{ - my $interface = shift; - my $function = shift; - - # if ($interface->name eq "NodeSet" && $function->signature->name eq "toDocumentOrder") { - # print Dumper($interface); - # print Dumper($function); - # } - - return "to_document_order" if ($interface->name eq "NodeSet" && $function->signature->name eq "toDocumentOrder"); - - return $function->signature->name; - -} - -sub IdlToWrapperAttrSetter -{ - my $idlAttr = shift; - return "set" . ucfirst($idlAttr); -} - - -sub IsReadonly -{ - my $attribute = shift; - my $attrExt = $attribute->signature->extendedAttributes; - return ($attribute->type =~ /readonly/ || $attrExt->{"V8ReadOnly"}) && !$attrExt->{"Replaceable"}; -} - - -my %non_wrapper_types = ( - 'CompareHow' => 1, - 'DOMObject' => 1, - 'DOMString' => 1, - 'DOMString[]' => 1, - 'DOMTimeStamp' => 1, - 'Date' => 1, - 'Dictionary' => 1, - 'EventListener' => 1, - # FIXME: When EventTarget is an interface and not a mixin, fix this so that - # EventTarget is treated as a wrapper type. - 'EventTarget' => 1, - 'IDBKey' => 1, - 'JSObject' => 1, - 'MediaQueryListListener' => 1, - 'NodeFilter' => 1, - 'any' => 1, - 'boolean' => 1, - 'double' => 1, - 'float' => 1, - 'int' => 1, - 'long long' => 1, - 'long' => 1, - 'long[]' => 1, - 'short' => 1, - 'short[]' => 1, - 'void' => 1, - 'byte' => 1, - 'byte[]' => 1, - 'octet' => 1, - 'char' => 1, - 'float[]' => 1, - 'float' => 1, - 'double[]' => 1, - 'octet[]' => 1, - 'double' => 1, - 'unsigned int' => 1, - 'unsigned long long' => 1, - 'unsigned long' => 1, - 'unsigned long[]' => 1, - 'unsigned short' => 1, - 'unsigned short[]' => 1 -); - -sub IsWrapperType -{ - my $type = shift; - return !($non_wrapper_types{$type}); -} - -sub GenerateHeaderContentHeader -{ - my $interface = shift; - my $v8InterfaceName = "V8" . $interface->name; - my $conditionalString = $codeGenerator->GenerateConditionalString($interface); - - my @headerContentHeader = split("\r", $headerTemplate); - - push(@headerContentHeader, "\n#if ${conditionalString}\n") if $conditionalString; - push(@headerContentHeader, "\n#ifndef ${v8InterfaceName}" . "_h"); - push(@headerContentHeader, "\n#define ${v8InterfaceName}" . "_h\n\n"); - return @headerContentHeader; -} - -1; diff --git a/contrib/dom/scripts/CodeGeneratorArabicaV8.pm.new b/contrib/dom/scripts/CodeGeneratorArabicaV8.pm.new deleted file mode 100644 index cbe33e8..0000000 --- a/contrib/dom/scripts/CodeGeneratorArabicaV8.pm.new +++ /dev/null @@ -1,1018 +0,0 @@ -# Copyright (C) 2005, 2006 Nikolas Zimmermann -# Copyright (C) 2006 Anders Carlsson -# Copyright (C) 2006 Samuel Weinig -# Copyright (C) 2006 Alexey Proskuryakov -# Copyright (C) 2006 Apple Computer, Inc. -# Copyright (C) 2007, 2008, 2009, 2012 Google Inc. -# Copyright (C) 2009 Cameron McCormack -# Copyright (C) Research In Motion Limited 2010. All rights reserved. -# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) -# Copyright (C) 2012 Ericsson AB. All rights reserved. -# Copyright (C) 2013 Stefan Radomski -# -# 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. -# - -package CodeGeneratorArabicaV8; - -use strict; -use Data::Dumper; -use Carp qw/longmess cluck confess/; - -use constant FileNamePrefix => "V8"; - -my $codeGenerator; - - -my @headerContent = (); -my @implContentHeader = (); -my @implContent = (); -my @implContentDecls = (); -my %implIncludes = (); -my %headerIncludes = (); - -# Default .h template -my $headerTemplate = << 'EOF'; -/** - * @file - * @author This file has been generated by generate-bindings.pl. DO NOT MODIFY! - * @copyright Simplified BSD - * - * @cond - * This program is free software: you can redistribute it and/or modify - * it under the terms of the FreeBSD license as published by the FreeBSD - * project. - * - * This program 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. - * - * You should have received a copy of the FreeBSD license along with this - * program. If not, see . - * @endcond - */ - -EOF - -# Default constructor -sub new -{ - my $object = shift; - my $reference = { }; - - $codeGenerator = shift; - - bless($reference, $object); - return $reference; -} - -sub GenerateInterface -{ - my $object = shift; - my $interface = shift; - -# print Dumper($interface); - - # Start actual generation - if ($interface->extendedAttributes->{"Callback"}) { - die(); - $object->GenerateCallbackHeader($interface); - $object->GenerateCallbackImplementation($interface); - } else { - $object->GenerateHeader($interface); - $object->GenerateImplementation($interface); - } -} - -sub AddToImplIncludes -{ - my $header = shift; - my $conditional = shift; - - if ($header eq "V8bool.h") { - confess(); - } - - if (not $conditional) { - $implIncludes{$header} = 1; - } elsif (not exists($implIncludes{$header})) { - $implIncludes{$header} = $conditional; - } else { - my $oldValue = $implIncludes{$header}; - if ($oldValue ne 1) { - my %newValue = (); - $newValue{$conditional} = 1; - foreach my $condition (split(/\|/, $oldValue)) { - $newValue{$condition} = 1; - } - $implIncludes{$header} = join("|", sort keys %newValue); - } - } -} - -sub GenerateHeader -{ - my $object = shift; - my $interface = shift; - my $interfaceName = $interface->name; - my $extensions = $interface->extendedAttributes; -# print Dumper($extensions); - - # Copy contents of parent interfaces except the first parent. - my @parents; - $codeGenerator->AddMethodsConstantsAndAttributesFromParentInterfaces($interface, \@parents, 1); - $codeGenerator->LinkOverloadedFunctions($interface); - - # - Add default header template - push(@headerContent, GenerateHeaderContentHeader($interface)); - - $headerIncludes{"string"} = 1; - $headerIncludes{"uscxml/plugins/datamodel/ecmascript/v8/V8DOM.h"} = 1; - $headerIncludes{"DOM/Node.hpp"} = 1; - $headerIncludes{"v8.h"} = 1; - - if ($interfaceName =~ /.*Array$/ or $interfaceName =~ /^ArrayBuffer.*/) { - $headerIncludes{"../../TypedArray.h"} = 1; - } - - foreach (@{$interface->parents}) { - my $parent = $_; - $headerIncludes{"V8${parent}.h"} = 1; - } - - push(@headerContent, "#include \\n"); - foreach my $headerInclude (sort keys(%headerIncludes)) { - if ($headerInclude =~ /wtf|v8\.h/) { - push(@headerContent, "#include \<${headerInclude}\>\n"); - } else { - push(@headerContent, "#include \"${headerInclude}\"\n"); - } - } - - push(@headerContent, ""); - push(@headerContent, "\nnamespace Arabica {"); - push(@headerContent, "\nnamespace DOM {\n"); - - push(@headerContent, "\nclass V8${interfaceName} {"); - push(@headerContent, "\npublic:"); - - my $wrapperType = IdlToWrapperType($interfaceName); - push(@headerContent, <{'DontDestroyWrapped'}) { - push(@headerContent, "\n V8_DESTRUCTOR_KEEP_WRAPPED(V8${interfaceName}Private);"); - } else { - push(@headerContent, "\n V8_DESTRUCTOR(V8${interfaceName}Private);"); - } - push(@headerContent, "\n static bool hasInstance(v8::Handle);"); - push(@headerContent, "\n"); - - # callbacks for actual functions - my %generated; - foreach my $function (@{$interface->functions}) { - my $name = $function->signature->name; - my $attrExt = $function->signature->extendedAttributes; - my $custom = ($attrExt->{'Custom'} ? "Custom" : ""); - next if (exists $generated{"${name}${custom}Callback"}); - push(@headerContent, "\n static void ${name}${custom}Callback(const v8::FunctionCallbackInfo&);"); - $generated{"${name}${custom}Callback"} = 1; - } - push(@headerContent, "\n"); - - # attribute getter and setters - foreach my $attribute (@{$interface->attributes}) { - my $name = $attribute->signature->name; - my $attrExt = $attribute->signature->extendedAttributes; - my $customGetter = ($attrExt->{'CustomGetter'} ? "Custom" : ""); - my $customSetter = ($attrExt->{'CustomSetter'} ? "Custom" : ""); - push(@headerContent, "\n static void ${name}${customGetter}AttrGetter(v8::Local property, const v8::PropertyCallbackInfo& info);"); - if (!IsReadonly($attribute)) { - push(@headerContent, "\n static void ${name}${customSetter}AttrSetter(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info);"); - } - } - - if ($extensions->{'CustomIndexedGetter'}) { - push(@headerContent, "\n static void indexedPropertyCustomGetter(uint32_t, const v8::AccessorInfo&);"); - } - if ($extensions->{'CustomIndexedSetter'}) { - push(@headerContent, "\n static void indexedPropertyCustomSetter(uint32_t, v8::Local, const v8::AccessorInfo&);"); - } - push(@headerContent, "\n"); - - GenerateClassPrototypeHeader($interface); - - push(@headerContent, "\n};\n\n}\n}\n\n"); - push(@headerContent, "#endif // V8${interfaceName}" . "_h\n"); - -} - -# -# Write class template prototype constructor -# -sub GenerateClassPrototypeHeader -{ - my $interface = shift; - my $interfaceName = $interface->name; - my $extensions = $interface->extendedAttributes; - - if ($extensions->{'Constructors'}) { - - push(@headerContent, "\n"); - push(@headerContent, " static void constructor(const v8::FunctionCallbackInfo&);\n"); - push(@headerContent, < getConstructor(v8::Isolate* isolate) { - return v8::FunctionTemplate::New(isolate, constructor); - } -END - } - - push(@headerContent, < getTmpl(v8::Isolate* isolate) { - v8::Handle tmpl = v8::FunctionTemplate::New(); - tmpl->SetClassName(v8::String::NewFromUtf8(isolate, "${interfaceName}")); - tmpl->ReadOnlyPrototype(); - - v8::Local instance = tmpl->InstanceTemplate(); - v8::Local prototype = tmpl->PrototypeTemplate(); - (void)prototype; // surpress unused warnings - - instance->SetInternalFieldCount(1); -END - - push(@headerContent, "\n"); - foreach my $attribute (@{$interface->attributes}) { - my $name = $attribute->signature->name; - my $attrExt = $attribute->signature->extendedAttributes; - my $customGetter = ($attrExt->{'CustomGetter'} ? "Custom" : ""); - my $customSetter = ($attrExt->{'CustomSetter'} ? "Custom" : ""); - my $getter = "V8${interfaceName}::${name}${customGetter}AttrGetter"; - my $setter = (IsReadonly($attribute) ? "0" : "V8${interfaceName}::${name}${customSetter}AttrSetter"); - push(@headerContent, <SetAccessor(v8::String::NewFromUtf8(isolate, "${name}"), ${getter}, ${setter}, - v8::External::New(isolate, 0), static_cast(v8::DEFAULT), static_cast(v8::None)); -END - } - - if ($extensions->{'CustomIndexedGetter'} || $extensions->{'CustomIndexedSetter'}) { - my $indexedGetter = ($extensions->{'CustomIndexedGetter'} ? "V8${interfaceName}::indexedPropertyCustomGetter" : 0); - my $indexedSetter = ($extensions->{'CustomIndexedSetter'} ? "V8${interfaceName}::indexedPropertyCustomSetter" : 0); - push(@headerContent, "\n instance->SetIndexedPropertyHandler(${indexedGetter}, ${indexedSetter});"); - } - - push(@headerContent, "\n"); - my %generated; - foreach my $function (@{$interface->functions}) { - my $name = $function->signature->name; - my $attrExt = $function->signature->extendedAttributes; - my $custom = ($attrExt->{'Custom'} ? "Custom" : ""); - next if (exists $generated{"${name}"}); - $generated{"${name}"} = 1; - push(@headerContent, <Set(v8::String::NewFromUtf8(isolate, "${name}"), - v8::FunctionTemplate::New(isolate, V8${interfaceName}::${name}${custom}Callback, v8::Undefined(isolate)), static_cast(v8::DontDelete)); -END - } - - push(@headerContent, "\n"); - foreach my $constant (@{$interface->constants}) { - my $name = $constant->name; - my $value = $constant->value; - my $type = IdlToV8Type($constant->type); - push(@headerContent, <Set(v8::String::NewFromUtf8(isolate, "${name}"), ${type}::New(${value}), static_cast(v8::ReadOnly | v8::DontEnum)); - prototype->Set(v8::String::NewFromUtf8(isolate, "${name}"), ${type}::New(${value}), static_cast(v8::ReadOnly | v8::DontEnum)); -END - } - - push(@headerContent, "\n"); - if (@{$interface->parents}) { - my $parent = @{$interface->parents}[0]; - push(@headerContent, " tmpl->Inherit(V8${parent}::getTmpl());\n"); - } - push(@headerContent, <name; - my $extensions = $interface->extendedAttributes; - - # Generate property accessors for attributes. - for (my $index = 0; $index < @{$interface->attributes}; $index++) { - my $attribute = @{$interface->attributes}[$index]; - my $attrType = $attribute->signature->type; - my $attrName = $attribute->signature->name; - my $attrExt = $attribute->signature->extendedAttributes; - - my $wrapperRetType = IdlToWrapperType($attrType); - my $wrapperType = IdlToWrapperType($interfaceName); - my $wrapperGetter; - - if ($attrExt->{'AttributeIsPublic'} || $extensions->{'AttributesArePublic'}) { - $wrapperGetter = $attrName; - } else { - $wrapperGetter = IdlToWrapperAttrGetter($interface, $attribute)."()"; - - } - - # getter - if (!$attrExt->{'CustomGetter'}) { - push(@implContent, < property, const v8::PropertyCallbackInfo& info) { - v8::Isolate* isolate = args.GetIsolate(); - v8::Local self = info.Holder(); - struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0)); -END - if (IsWrapperType($attrType)) { - AddToImplIncludes("V8".$attrType.".h"); - push(@implContent, "\n ".GenerateConditionalUndefReturn($interface, $attribute, "privData->nativeObj->${wrapperGetter}")); - - push(@implContent, <nativeObj->${wrapperGetter}); - - v8::Handle arbaicaRetCtor = V8${attrType}::getTmpl(isolate)->GetFunction(); - v8::Persistent arbaicaRetObj = v8::Persistent::New(arbaicaRetCtor->NewInstance()); - - struct V8${attrType}::V8${attrType}Private* retPrivData = new V8${attrType}::V8${attrType}Private(); - retPrivData->dom = privData->dom; - retPrivData->nativeObj = arbaicaRet; - - arbaicaRetObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - arbaicaRetObj.MakeWeak(0, V8${attrType}::jsDestructor); - return arbaicaRetObj; -END - } else { - my $v8Type = IdlToV8Type($attrType); - if ($attrType eq "DOMString") { - if ($attrExt->{'EmptyAsNull'}) { - push(@implContent, "\n if (privData->nativeObj->${wrapperGetter}.length() == 0)"); - push(@implContent, "\n return v8::Undefined(isolate);"); - } - push(@implContent, "\n return ${v8Type}::New(privData->nativeObj->${wrapperGetter}.c_str());"); - } else { - push(@implContent, "\n return ${v8Type}::New(privData->nativeObj->${wrapperGetter});"); - } - } - push(@implContent, "\n }\n"); - } - - if (!$attrExt->{'CustomSetter'}) { - # setter - if (!IsReadonly($attribute)) { - my $wrapperSetter = IdlToWrapperAttrSetter($attrName); - push(@implContent, "\n void V8${interfaceName}::${attrName}AttrSetter(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info) {"); - push(@implContent, "\n v8::Isolate* isolate = args.GetIsolate();"); - push(@implContent, "\n v8::Local self = info.Holder();"); - push(@implContent, "\n struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0));"); - - my ($handle, $deref) = IdlToArgHandle($attribute->signature->type, "local".ucfirst($attribute->signature->name), "value", $interfaceName); - - push(@implContent, "\n $handle"); - push(@implContent, "\n privData->nativeObj->${wrapperSetter}(${deref});"); - push(@implContent, "\n }\n"); - - } - } - } -} - -sub GenerateConditionalUndefReturn -{ - my $interface = shift; - my $attribute = shift; - my $getterExpression = shift; - - return "" if ($attribute->signature->type eq "NamedNodeMap"); - return "" if ($attribute->signature->type eq "NodeList"); - return "if (!$getterExpression) return v8::Undefined(isolate);"; -} - -sub GenerateConstructor -{ - my $interface = shift; - my $interfaceName = $interface->name; - my $wrapperType = IdlToWrapperType($interfaceName); - my $extensions = $interface->extendedAttributes; - - if ($extensions->{'Constructors'}) { - - push(@implContent, "\n void V8${interfaceName}::constructor(const v8::FunctionCallbackInfo& args) {"); - push(@implContent, <ThrowException(v8::String::NewFromUtf8(isolate, "Cannot call constructor as function")); - return; - } -END - - push(@implContent, "\n ".IdlToWrapperType($interfaceName)."* localInstance = NULL;"); - # dispatch the actual constructor - push(@implContent, "\n if (false) {\n}"); - my @variants; - foreach my $fullCons (@{$extensions->{'Constructors'}}) { - push (@variants, $fullCons); - - for (my $i = @{$fullCons}; $i > 0; $i--) { - my $variant = @{$fullCons}[$i]; - if ($variant->{'domSignature::isOptional'}) { - my $slice; - for (my $j = 0; $j < $i; $j++) { - push(@{$slice}, @{$fullCons}[$j]); - } - push (@variants, $slice); - } - } - - # sort to put most determinate signatures first - @variants = sort { - if (@{$b} != @{$a}) { - # more arguments are more determinant - @{$b} <=> @{$a}; - } else { - my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a}); - my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b}); - @bWrap <=> @aWrap; - } - } @variants; - } - foreach my $constructor (@variants) { - push(@implContent, " else if (args.Length() == " . @{$constructor}); - - for (my $i = 0; $i < @{$constructor}; $i++) { - my $type = $constructor->[$i]->{'domSignature::type'}; - AddToImplIncludes("V8".$type.".h") if (IsWrapperType($type)); - push(@implContent, " &&\n " . IdlToTypeChecker($type, "args[$i]")); - - } - push(@implContent, ") {\n"); - my $constructorArgs; - my $constructorSep = ""; - for (my $i = 0; $i < @{$constructor}; $i++) { - my $type = $constructor->[$i]->{'domSignature::type'}; - my $name = $constructor->[$i]->{'domSignature::name'}; - my ($handle, $deref) = IdlToArgHandle($type, "local".ucfirst($name), "args[$i]", $interfaceName); - $constructorArgs .= ${constructorSep}.${deref}; - $constructorSep = ", "; - push(@implContent, "\n $handle"); - - } - push(@implContent, "\n localInstance = new ".IdlToWrapperType($interfaceName)."(${constructorArgs});"); - push(@implContent, "\n\n }"); - } - push(@implContent, "\n"); - - push(@implContent, < retCtor = V8${interfaceName}::getTmpl(isolate)->GetFunction(); - v8::Persistent retObj = v8::Persistent::New(retCtor->NewInstance()); - - struct V8${interfaceName}::V8${interfaceName}Private* retPrivData = new V8${interfaceName}::V8${interfaceName}Private(); - retPrivData->nativeObj = localInstance; - - retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - retObj.MakeWeak(0, V8${interfaceName}::jsDestructor); - - args.GetReturnValue().Set(retObj); - return; - } -END - } - -} - -sub GenerateImplementationFunctionCallbacks -{ - my $interface = shift; - my $interfaceName = $interface->name; - my $wrapperType = IdlToWrapperType($interfaceName); - my $extensions = $interface->extendedAttributes; - - - # Generate methods for functions. - my %generated; - foreach my $function (@{$interface->functions}) { - my $name = $function->signature->name; - my $attrExt = $function->signature->extendedAttributes; - my $retType = $function->signature->type; - my $wrapperRetType = IdlToWrapperType($retType); - - next if ($attrExt->{'Custom'}); - next if (exists $generated{"${name}Callback"}); - $generated{"${name}Callback"} = 1; - - # get all functions with this name - my @sameFunctions = grep($_->signature->name eq $name, @{$interface->functions}); - - # signature - push(@implContent, <& args) { - v8::Isolate* isolate = args.GetIsolate(); -END - - # get this - push(@implContent, "\n v8::Local self = args.Holder();"); - push(@implContent, "\n struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0));"); - - # establish all variants - my @variants; - foreach my $functionVar (@sameFunctions) { - push (@variants, $functionVar->parameters); - - for (my $i = @{$functionVar->parameters}; $i > 0; $i--) { - my $variant = @{$functionVar->parameters}[$i]; - if ($variant->{'domSignature::isOptional'}) { - my $slice; - for (my $j = 0; $j < $i; $j++) { - push(@{$slice}, @{$functionVar->parameters}[$j]); - } - push (@variants, $slice); - } - } - } - - # arguments to local handles - push(@implContent, "\n if (false) {"); - - # sort to put most determinate signatures first - @variants = sort { - if (@{$b} != @{$a}) { - # more arguments are more determinant - @{$b} <=> @{$a}; - } else { - my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a}); - my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b}); - @bWrap <=> @aWrap; - } - } @variants; - - foreach my $variant (@variants) { - my $parameterIndex = 0; - my @argList; - - push(@implContent, "\n } else if (args.Length() == " . @{$variant}); - for (my $i = 0; $i < @{$variant}; $i++) { - my $type = $variant->[$i]->{'domSignature::type'}; - push(@implContent, " &&\n " . IdlToTypeChecker($type, "args[$i]")); - } - push(@implContent, ")\n {"); - foreach my $parameter (@{$variant}) { - my $value = "args[$parameterIndex]"; - my $type = $parameter->type; - AddToImplIncludes("V8".$type.".h") if (IsWrapperType($type)); - - my ($handle, $deref) = IdlToArgHandle($parameter->type, "local".ucfirst($parameter->name), "args[${parameterIndex}]", $interfaceName); - push(@implContent, "\n ${handle}"); - push(@argList, $deref); - $parameterIndex++; - } - - # invoke native function with argument handles - my $retNativeType = IdlToNativeType($retType); - my $wrapperFunctionName = IdlToWrapperFunction($interface, $function); - if (IsWrapperType($retType)) { - push(@implContent, "\n\n ${retNativeType}* retVal = new $wrapperRetType(privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . "));\n"); - } elsif ($retNativeType eq "void") { - push(@implContent, "\n\n privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n"); - } else { - push(@implContent, "\n\n ${retNativeType} retVal = privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n"); - } - - # wrap return type if needed - if (IsWrapperType($retType)) { - AddToImplIncludes("V8".$retType.".h"); - - push(@implContent, < retCtor = V8${retType}::getTmpl(isolate)->GetFunction(); - v8::Persistent retObj = v8::Persistent::New(retCtor->NewInstance()); - - struct V8${retType}::V8${retType}Private* retPrivData = new V8${retType}::V8${retType}Private(); - retPrivData->dom = privData->dom; - retPrivData->nativeObj = retVal; - - retObj->SetInternalField(0, V8DOM::toExternal(retPrivData)); - - retObj.MakeWeak(0, V8${retType}::jsDestructor); - return retObj; -END - } else { - my $toHandleString = NativeToHandle($retNativeType, "retVal"); - push(@implContent, "\n return ${toHandleString};"); - } - } - push(@implContent, <name; - my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface); - my $v8InterfaceName = "V8$interfaceName"; - my $wrapperType = IdlToWrapperType($interfaceName); - my $extensions = $interface->extendedAttributes; - - AddToImplIncludes("V8${interfaceName}.h"); - - # Find the super descriptor. - my $parentClass = ""; - my $parentClassTemplate = ""; - foreach (@{$interface->parents}) { - my $parent = $_; - AddToImplIncludes("V8${parent}.h"); - $parentClass = "V8" . $parent; - last; - } - - push(@implContent, "namespace Arabica {\n"); - push(@implContent, "namespace DOM {\n\n"); - - if ($extensions->{'Constructors'}) { - GenerateConstructor($interface); - } - - GenerateImplementationAttributes($interface); - GenerateImplementationFunctionCallbacks($interface); - - - push(@implContent, < value) { - return getTmpl()->HasInstance(value); - } - -} -} -END - - # We've already added the header for this file in implContentHeader, so remove - # it from implIncludes to ensure we don't #include it twice. -# delete $implIncludes{"${v8InterfaceName}.h"}; -} - -sub WriteData -{ - my $object = shift; - my $interface = shift; - my $outputDir = shift; - my $outputHeadersDir = shift; - - my $name = $interface->name; - my $prefix = FileNamePrefix; - my $headerFileName = "$outputHeadersDir/$prefix$name.h"; - my $implFileName = "$outputDir/$prefix$name.cpp"; - - # print "WriteData\n"; - # print Dumper($interface); - # exit(); - - # Update a .cpp file if the contents are changed. - my $contents = $headerTemplate; - $contents .= join "", @implContentHeader; - - my @includes = (); - my %implIncludeConditions = (); - foreach my $include (keys %implIncludes) { - my $condition = $implIncludes{$include}; - my $checkType = $include; - $checkType =~ s/\.h//; - next if $codeGenerator->IsSVGAnimatedType($checkType); - - if ($include =~ /wtf/) { - $include = "\<$include\>"; - } else { - $include = "\"$include\""; - } - - if ($condition eq 1) { - push @includes, $include; - } else { - push @{$implIncludeConditions{$condition}}, $include; - } - } - foreach my $include (sort @includes) { - $contents .= "#include $include\n"; - } - foreach my $condition (sort keys %implIncludeConditions) { - $contents .= "\n#if " . $codeGenerator->GenerateConditionalStringFromAttributeValue($condition) . "\n"; - foreach my $include (sort @{$implIncludeConditions{$condition}}) { - $contents .= "#include $include\n"; - } - $contents .= "#endif\n"; - } - - $contents .= "\n"; - $contents .= join "", @implContentDecls, @implContent; - $codeGenerator->UpdateFile($implFileName, $contents); - - %implIncludes = (); - @implContentHeader = (); - @implContentDecls = (); - @implContent = (); - - # Update a .h file if the contents are changed. - $contents = join "", @headerContent; - $codeGenerator->UpdateFile($headerFileName, $contents); - - @headerContent = (); -} - -sub IdlToV8Type -{ - my $idlType = shift; - return "v8::Integer" if ($idlType eq "unsigned short"); - return "v8::Integer" if ($idlType eq "short"); - return "v8::Integer" if ($idlType eq "unsigned long"); - return "v8::Integer" if ($idlType eq "long"); - return "v8::String" if ($idlType eq "DOMString"); - return "v8::Boolean" if ($idlType eq "boolean"); - return "v8::Number" if ($idlType eq "double"); - die($idlType); -} - -sub IdlToNativeType -{ - my $idlType = shift; - - return IdlToWrapperType($idlType) if (IsWrapperType($idlType)); - - return "std::string" if ($idlType eq "DOMString"); - return "bool" if ($idlType eq "boolean"); - return "short" if ($idlType eq "short"); - return "long" if ($idlType eq "long"); - return "unsigned short" if ($idlType eq "unsigned short"); - return "unsigned long" if ($idlType eq "unsigned long"); - return "void" if ($idlType eq "void"); - return "char" if ($idlType eq "byte"); - return "unsigned char" if ($idlType eq "octet"); - return "double" if ($idlType eq "double"); - return "float" if ($idlType eq "float"); - die(${idlType}); -} - -sub NativeToHandle -{ - my $nativeType = shift; - my $nativeName = shift; - - return ("v8::Boolean::New(${nativeName})") if ($nativeType eq "bool"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "double"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "double"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "float"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "short"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "char"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned short"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned long"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "unsigned char"); - return ("v8::Number::New(${nativeName})") if ($nativeType eq "long"); - return ("v8::String::NewFromUtf8(isolate, ${nativeName}.c_str())") if ($nativeType eq "std::string"); - return ("v8::Undefined(isolate)") if ($nativeType eq "void"); - - die($nativeType); -} - -sub IdlToWrapperType -{ - my $idlType = shift; - return "Arabica::XPath::XPathValue" if ($idlType eq "XPathResult"); - return "Arabica::XPath::NodeSet" if ($idlType eq "NodeSet"); - return "Arabica::DOM::Node" if ($idlType eq "Node"); - return "Arabica::DOM::Element" if ($idlType eq "Element"); - return "uscxml::Event" if ($idlType eq "SCXMLEvent"); - return "uscxml::Storage" if ($idlType eq "Storage"); - return "uscxml::ArrayBuffer" if ($idlType eq "ArrayBuffer"); - return "uscxml::ArrayBufferView" if ($idlType eq "ArrayBufferView"); - return "uscxml::Int8Array" if ($idlType eq "Int8Array"); - return "uscxml::Uint8Array" if ($idlType eq "Uint8Array"); - return "uscxml::Uint8ClampedArray" if ($idlType eq "Uint8ClampedArray"); - return "uscxml::Int16Array" if ($idlType eq "Int16Array"); - return "uscxml::Uint16Array" if ($idlType eq "Uint16Array"); - return "uscxml::Int32Array" if ($idlType eq "Int32Array"); - return "uscxml::Uint32Array" if ($idlType eq "Uint32Array"); - return "uscxml::Float32Array" if ($idlType eq "Float32Array"); - return "uscxml::Float64Array" if ($idlType eq "Float64Array"); - return "uscxml::DataView" if ($idlType eq "DataView"); - return "Arabica::DOM::${idlType}"; -} - -sub IdlToArgHandle -{ - my $type = shift; - my $localName = shift; - my $paramName = shift; - my $thisType = shift; - - return ("v8::String::AsciiValue ${localName}(${paramName});", "*${localName}") if ($type eq "DOMString"); - return ("unsigned long ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "unsigned long"); - return ("long ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "long"); - return ("double ${localName} = ${paramName}->ToNumber()->Value();", ${localName}) if ($type eq "double"); - return ("float ${localName} = ${paramName}->ToNumber()->Value();", ${localName}) if ($type eq "float"); - return ("unsigned short ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "unsigned short"); - return ("bool ${localName} = ${paramName}->ToBoolean()->BooleanValue();", ${localName}) if ($type eq "boolean"); - return ("char ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "byte"); - return ("short ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "short"); - return ("unsigned char ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "octet"); - return ("void* ${localName} = v8::External::Unwrap(${paramName}->ToObject()->GetInternalField(0));", ${localName}) if ($type eq "any"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInteger()->Value());\n}", "${localName}") if ($type eq "long[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "float[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "double[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "byte[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "short[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned short[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned long[]"); - return ("std::vector ${localName};\nv8::Handle ${localName}Array(v8::Array::Cast(*args[0]));\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "octet[]"); - - if (IsWrapperType($type)) { - my $wrapperType = IdlToWrapperType($type); - if ($type =~ /.*Array$/ or $type =~ /^ArrayBuffer.*/) { - return ("${wrapperType}* ${localName} = V8DOM::toClassPtr(${paramName}->ToObject()->GetInternalField(0))->nativeObj;", "${localName}"); - } - - return ("${wrapperType}* ${localName} = V8DOM::toClassPtr(${paramName}->ToObject()->GetInternalField(0))->nativeObj;", "*${localName}"); - } - - print $type."\n"; - die(); -} - -sub IdlToTypeChecker -{ - my $idlType = shift; - my $attr = shift; - - return $attr."->IsString()" if ($idlType eq "DOMString"); - return $attr."->IsBoolean()" if ($idlType eq "boolean"); - return $attr."->IsInt32()" if ($idlType eq "short"); - return $attr."->IsInt32()" if ($idlType eq "long"); - return $attr."->IsArray()" if ($idlType eq "long[]"); - return $attr."->IsUint32()" if ($idlType eq "unsigned short"); - return $attr."->IsUint32()" if ($idlType eq "unsigned long"); - return $attr."->IsInt32()" if ($idlType eq "byte"); - return $attr."->IsUint32()" if ($idlType eq "octet"); - return $attr."->IsNumber()" if ($idlType eq "double"); - return $attr."->IsArray()" if ($idlType eq "double[]"); - return $attr."->IsNumber()" if ($idlType eq "float"); - return $attr."->IsArray()" if ($idlType eq "float[]"); - return $attr."->IsArray()" if ($idlType eq "short[]"); - return $attr."->IsArray()" if ($idlType eq "unsigned short[]"); - return $attr."->IsArray()" if ($idlType eq "unsigned long[]"); - return $attr."->IsArray()" if ($idlType eq "byte[]"); - return $attr."->IsArray()" if ($idlType eq "octet[]"); - return "true" if ($idlType eq "any"); - - return $attr."->IsObject() && V8".$idlType."::hasInstance(".$attr.")" if (IsWrapperType($idlType)); - - print $idlType."\n"; - die(); - -} - -sub IdlToWrapperAttrGetter -{ - my $interface = shift; - my $attribute = shift; - - return $attribute->signature->name if ($interface->name eq "NodeSet" && $attribute->signature->name eq "size"); - return $attribute->signature->name if ($interface->name eq "NodeSet" && $attribute->signature->name eq "empty"); - return "asString" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "stringValue"); - return "asBool" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "booleanValue"); - return "asNumber" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "numberValue"); - - return "get" . ucfirst($attribute->signature->name); -} - -sub IdlToWrapperFunction -{ - my $interface = shift; - my $function = shift; - - # if ($interface->name eq "NodeSet" && $function->signature->name eq "toDocumentOrder") { - # print Dumper($interface); - # print Dumper($function); - # } - - return "to_document_order" if ($interface->name eq "NodeSet" && $function->signature->name eq "toDocumentOrder"); - - return $function->signature->name; - -} - -sub IdlToWrapperAttrSetter -{ - my $idlAttr = shift; - return "set" . ucfirst($idlAttr); -} - - -sub IsReadonly -{ - my $attribute = shift; - my $attrExt = $attribute->signature->extendedAttributes; - return ($attribute->type =~ /readonly/ || $attrExt->{"V8ReadOnly"}) && !$attrExt->{"Replaceable"}; -} - - -my %non_wrapper_types = ( - 'CompareHow' => 1, - 'DOMObject' => 1, - 'DOMString' => 1, - 'DOMString[]' => 1, - 'DOMTimeStamp' => 1, - 'Date' => 1, - 'Dictionary' => 1, - 'EventListener' => 1, - # FIXME: When EventTarget is an interface and not a mixin, fix this so that - # EventTarget is treated as a wrapper type. - 'EventTarget' => 1, - 'IDBKey' => 1, - 'JSObject' => 1, - 'MediaQueryListListener' => 1, - 'NodeFilter' => 1, - 'any' => 1, - 'boolean' => 1, - 'double' => 1, - 'float' => 1, - 'int' => 1, - 'long long' => 1, - 'long' => 1, - 'long[]' => 1, - 'short' => 1, - 'short[]' => 1, - 'void' => 1, - 'byte' => 1, - 'byte[]' => 1, - 'octet' => 1, - 'char' => 1, - 'float[]' => 1, - 'float' => 1, - 'double[]' => 1, - 'octet[]' => 1, - 'double' => 1, - 'unsigned int' => 1, - 'unsigned long long' => 1, - 'unsigned long' => 1, - 'unsigned long[]' => 1, - 'unsigned short' => 1, - 'unsigned short[]' => 1 -); - -sub IsWrapperType -{ - my $type = shift; - return !($non_wrapper_types{$type}); -} - -sub GenerateHeaderContentHeader -{ - my $interface = shift; - my $v8InterfaceName = "V8" . $interface->name; - my $conditionalString = $codeGenerator->GenerateConditionalString($interface); - - my @headerContentHeader = split("\r", $headerTemplate); - - push(@headerContentHeader, "\n#if ${conditionalString}\n") if $conditionalString; - push(@headerContentHeader, "\n#ifndef ${v8InterfaceName}" . "_h"); - push(@headerContentHeader, "\n#define ${v8InterfaceName}" . "_h\n\n"); - return @headerContentHeader; -} - -1; diff --git a/contrib/dom/scripts/CodeGeneratorArabicaV8.post3.14.pm b/contrib/dom/scripts/CodeGeneratorArabicaV8.post3.14.pm new file mode 100644 index 0000000..e913aaa --- /dev/null +++ b/contrib/dom/scripts/CodeGeneratorArabicaV8.post3.14.pm @@ -0,0 +1,1021 @@ +# Copyright (C) 2005, 2006 Nikolas Zimmermann +# Copyright (C) 2006 Anders Carlsson +# Copyright (C) 2006 Samuel Weinig +# Copyright (C) 2006 Alexey Proskuryakov +# Copyright (C) 2006 Apple Computer, Inc. +# Copyright (C) 2007, 2008, 2009, 2012 Google Inc. +# Copyright (C) 2009 Cameron McCormack +# Copyright (C) Research In Motion Limited 2010. All rights reserved. +# Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) +# Copyright (C) 2012 Ericsson AB. All rights reserved. +# Copyright (C) 2013 Stefan Radomski +# +# 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. +# + +package CodeGeneratorArabicaV8; + +use strict; +use Data::Dumper; +use Carp qw/longmess cluck confess/; + +use constant FileNamePrefix => "V8"; + +my $codeGenerator; + + +my @headerContent = (); +my @implContentHeader = (); +my @implContent = (); +my @implContentDecls = (); +my %implIncludes = (); +my %headerIncludes = (); + +# Default .h template +my $headerTemplate = << 'EOF'; +/** + * @file + * @author This file has been generated by generate-bindings.pl. DO NOT MODIFY! + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program 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. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see . + * @endcond + */ + +EOF + +# Default constructor +sub new +{ + my $object = shift; + my $reference = { }; + + $codeGenerator = shift; + + bless($reference, $object); + return $reference; +} + +sub GenerateInterface +{ + my $object = shift; + my $interface = shift; + +# print Dumper($interface); + + # Start actual generation + if ($interface->extendedAttributes->{"Callback"}) { + die(); + $object->GenerateCallbackHeader($interface); + $object->GenerateCallbackImplementation($interface); + } else { + $object->GenerateHeader($interface); + $object->GenerateImplementation($interface); + } +} + +sub AddToImplIncludes +{ + my $header = shift; + my $conditional = shift; + + if ($header eq "V8bool.h") { + confess(); + } + + if (not $conditional) { + $implIncludes{$header} = 1; + } elsif (not exists($implIncludes{$header})) { + $implIncludes{$header} = $conditional; + } else { + my $oldValue = $implIncludes{$header}; + if ($oldValue ne 1) { + my %newValue = (); + $newValue{$conditional} = 1; + foreach my $condition (split(/\|/, $oldValue)) { + $newValue{$condition} = 1; + } + $implIncludes{$header} = join("|", sort keys %newValue); + } + } +} + +sub GenerateHeader +{ + my $object = shift; + my $interface = shift; + my $interfaceName = $interface->name; + my $extensions = $interface->extendedAttributes; +# print Dumper($extensions); + + # Copy contents of parent interfaces except the first parent. + my @parents; + $codeGenerator->AddMethodsConstantsAndAttributesFromParentInterfaces($interface, \@parents, 1); + $codeGenerator->LinkOverloadedFunctions($interface); + + # - Add default header template + push(@headerContent, GenerateHeaderContentHeader($interface)); + + $headerIncludes{"string"} = 1; + $headerIncludes{"uscxml/plugins/datamodel/ecmascript/v8/V8DOM.h"} = 1; + $headerIncludes{"DOM/Node.hpp"} = 1; + $headerIncludes{"v8.h"} = 1; + + if ($interfaceName =~ /.*Array$/ or $interfaceName =~ /^ArrayBuffer.*/) { + $headerIncludes{"../../TypedArray.h"} = 1; + } + + foreach (@{$interface->parents}) { + my $parent = $_; + $headerIncludes{"V8${parent}.h"} = 1; + } + + push(@headerContent, "#include \\n"); + foreach my $headerInclude (sort keys(%headerIncludes)) { + if ($headerInclude =~ /wtf|v8\.h/) { + push(@headerContent, "#include \<${headerInclude}\>\n"); + } else { + push(@headerContent, "#include \"${headerInclude}\"\n"); + } + } + + push(@headerContent, ""); + push(@headerContent, "\nnamespace Arabica {"); + push(@headerContent, "\nnamespace DOM {\n"); + + push(@headerContent, "\nclass V8${interfaceName} {"); + push(@headerContent, "\npublic:"); + + my $wrapperType = IdlToWrapperType($interfaceName); + push(@headerContent, <{'DontDestroyWrapped'}) { + push(@headerContent, "\n V8_DESTRUCTOR_KEEP_WRAPPED(V8${interfaceName}Private);"); + } else { + push(@headerContent, "\n V8_DESTRUCTOR(V8${interfaceName}Private);"); + } + push(@headerContent, "\n static bool hasInstance(v8::Handle);"); + push(@headerContent, "\n"); + + # callbacks for actual functions + my %generated; + foreach my $function (@{$interface->functions}) { + my $name = $function->signature->name; + my $attrExt = $function->signature->extendedAttributes; + my $custom = ($attrExt->{'Custom'} ? "Custom" : ""); + next if (exists $generated{"${name}${custom}Callback"}); + push(@headerContent, "\n static void ${name}${custom}Callback(const v8::FunctionCallbackInfo&);"); + $generated{"${name}${custom}Callback"} = 1; + } + push(@headerContent, "\n"); + + # attribute getter and setters + foreach my $attribute (@{$interface->attributes}) { + my $name = $attribute->signature->name; + my $attrExt = $attribute->signature->extendedAttributes; + my $customGetter = ($attrExt->{'CustomGetter'} ? "Custom" : ""); + my $customSetter = ($attrExt->{'CustomSetter'} ? "Custom" : ""); + push(@headerContent, "\n static void ${name}${customGetter}AttrGetter(v8::Local property, const v8::PropertyCallbackInfo& info);"); + if (!IsReadonly($attribute)) { + push(@headerContent, "\n static void ${name}${customSetter}AttrSetter(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info);"); + } + } + + if ($extensions->{'CustomIndexedGetter'}) { + push(@headerContent, "\n static void indexedPropertyCustomGetter(uint32_t, const v8::PropertyCallbackInfo&);"); + } + if ($extensions->{'CustomIndexedSetter'}) { + push(@headerContent, "\n static void indexedPropertyCustomSetter(uint32_t, v8::Local, const v8::PropertyCallbackInfo&);"); + } + push(@headerContent, "\n"); + + GenerateClassPrototypeHeader($interface); + + push(@headerContent, "\n};\n\n}\n}\n\n"); + push(@headerContent, "#endif // V8${interfaceName}" . "_h\n"); + +} + +# +# Write class template prototype constructor +# +sub GenerateClassPrototypeHeader +{ + my $interface = shift; + my $interfaceName = $interface->name; + my $extensions = $interface->extendedAttributes; + + if ($extensions->{'Constructors'}) { + + push(@headerContent, "\n"); + push(@headerContent, " static void constructor(const v8::FunctionCallbackInfo&);\n"); + push(@headerContent, < getConstructor(v8::Isolate* isolate) { + return v8::FunctionTemplate::New(isolate, constructor); + } +END + } + + push(@headerContent, < getTmpl(v8::Isolate* isolate) { + v8::Handle tmpl = v8::FunctionTemplate::New(isolate); + tmpl->SetClassName(v8::String::NewFromUtf8(isolate, "${interfaceName}")); + tmpl->ReadOnlyPrototype(); + + v8::Local instance = tmpl->InstanceTemplate(); + v8::Local prototype = tmpl->PrototypeTemplate(); + (void)prototype; // surpress unused warnings + + instance->SetInternalFieldCount(1); +END + + push(@headerContent, "\n"); + foreach my $attribute (@{$interface->attributes}) { + my $name = $attribute->signature->name; + my $attrExt = $attribute->signature->extendedAttributes; + my $customGetter = ($attrExt->{'CustomGetter'} ? "Custom" : ""); + my $customSetter = ($attrExt->{'CustomSetter'} ? "Custom" : ""); + my $getter = "V8${interfaceName}::${name}${customGetter}AttrGetter"; + my $setter = (IsReadonly($attribute) ? "0" : "V8${interfaceName}::${name}${customSetter}AttrSetter"); + push(@headerContent, <SetAccessor(v8::String::NewFromUtf8(isolate, "${name}"), ${getter}, ${setter}, + v8::External::New(isolate, 0), static_cast(v8::DEFAULT), static_cast(v8::None)); +END + } + + if ($extensions->{'CustomIndexedGetter'} || $extensions->{'CustomIndexedSetter'}) { + my $indexedGetter = ($extensions->{'CustomIndexedGetter'} ? "V8${interfaceName}::indexedPropertyCustomGetter" : 0); + my $indexedSetter = ($extensions->{'CustomIndexedSetter'} ? "V8${interfaceName}::indexedPropertyCustomSetter" : 0); + push(@headerContent, "\n instance->SetIndexedPropertyHandler(${indexedGetter}, ${indexedSetter});"); + } + + push(@headerContent, "\n"); + my %generated; + foreach my $function (@{$interface->functions}) { + my $name = $function->signature->name; + my $attrExt = $function->signature->extendedAttributes; + my $custom = ($attrExt->{'Custom'} ? "Custom" : ""); + next if (exists $generated{"${name}"}); + $generated{"${name}"} = 1; + push(@headerContent, <Set(v8::String::NewFromUtf8(isolate, "${name}"), + v8::FunctionTemplate::New(isolate, V8${interfaceName}::${name}${custom}Callback, v8::Undefined(isolate)), static_cast(v8::DontDelete)); +END + } + + push(@headerContent, "\n"); + foreach my $constant (@{$interface->constants}) { + my $name = $constant->name; + my $value = $constant->value; + my $type = IdlToV8Type($constant->type); + push(@headerContent, <Set(v8::String::NewFromUtf8(isolate, "${name}"), ${type}::New(isolate, ${value}), static_cast(v8::ReadOnly | v8::DontEnum)); + prototype->Set(v8::String::NewFromUtf8(isolate, "${name}"), ${type}::New(isolate, ${value}), static_cast(v8::ReadOnly | v8::DontEnum)); +END + } + + push(@headerContent, "\n"); + if (@{$interface->parents}) { + my $parent = @{$interface->parents}[0]; + push(@headerContent, " tmpl->Inherit(V8${parent}::getTmpl(isolate));\n"); + } + push(@headerContent, <name; + my $extensions = $interface->extendedAttributes; + + # Generate property accessors for attributes. + for (my $index = 0; $index < @{$interface->attributes}; $index++) { + my $attribute = @{$interface->attributes}[$index]; + my $attrType = $attribute->signature->type; + my $attrName = $attribute->signature->name; + my $attrExt = $attribute->signature->extendedAttributes; + + my $wrapperRetType = IdlToWrapperType($attrType); + my $wrapperType = IdlToWrapperType($interfaceName); + my $wrapperGetter; + + if ($attrExt->{'AttributeIsPublic'} || $extensions->{'AttributesArePublic'}) { + $wrapperGetter = $attrName; + } else { + $wrapperGetter = IdlToWrapperAttrGetter($interface, $attribute)."()"; + + } + + # getter + if (!$attrExt->{'CustomGetter'}) { + push(@implContent, < property, const v8::PropertyCallbackInfo& info) { + v8::Isolate* isolate = info.GetIsolate(); + v8::Local self = info.Holder(); + struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0)); +END + if (IsWrapperType($attrType)) { + AddToImplIncludes("V8".$attrType.".h"); + push(@implContent, "\n ".GenerateConditionalUndefReturn($interface, $attribute, "privData->nativeObj->${wrapperGetter}")); + + push(@implContent, <nativeObj->${wrapperGetter}); + + v8::Handle arbaicaRetCtor = V8${attrType}::getTmpl(isolate)->GetFunction(); + v8::Persistent arbaicaRetObj(isolate, arbaicaRetCtor->NewInstance()); + + struct V8${attrType}::V8${attrType}Private* retPrivData = new V8${attrType}::V8${attrType}Private(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = arbaicaRet; + + arbaicaRetObj.Get(isolate)->SetInternalField(0, V8DOM::toExternal(retPrivData)); + arbaicaRetObj.SetWeak(0, V8${attrType}::jsDestructor); + info.GetReturnValue().Set(arbaicaRetObj); + // return arbaicaRetObj; +END + } else { + my $v8Type = IdlToV8Type($attrType); + if ($attrType eq "DOMString") { + if ($attrExt->{'EmptyAsNull'}) { + push(@implContent, "\n if (privData->nativeObj->${wrapperGetter}.length() == 0)"); + push(@implContent, "\n return; //v8::Undefined(isolate);"); + } + push(@implContent, "\n info.GetReturnValue().Set(${v8Type}::NewFromUtf8(isolate, privData->nativeObj->${wrapperGetter}.c_str()));"); + # push(@implContent, "\n return ${v8Type}::New(privData->nativeObj->${wrapperGetter}.c_str());"); + } else { + push(@implContent, "\n info.GetReturnValue().Set(${v8Type}::New(isolate, privData->nativeObj->${wrapperGetter}));"); + } + } + push(@implContent, "\n }\n"); + } + + if (!$attrExt->{'CustomSetter'}) { + # setter + if (!IsReadonly($attribute)) { + my $wrapperSetter = IdlToWrapperAttrSetter($attrName); + push(@implContent, "\n void V8${interfaceName}::${attrName}AttrSetter(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info) {"); + push(@implContent, "\n v8::Isolate* isolate = info.GetIsolate();"); + push(@implContent, "\n v8::Local self = info.Holder();"); + push(@implContent, "\n struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0));"); + + my ($handle, $deref) = IdlToArgHandle($attribute->signature->type, "local".ucfirst($attribute->signature->name), "value", $interfaceName); + + push(@implContent, "\n $handle"); + push(@implContent, "\n privData->nativeObj->${wrapperSetter}(${deref});"); + push(@implContent, "\n }\n"); + + } + } + } +} + +sub GenerateConditionalUndefReturn +{ + my $interface = shift; + my $attribute = shift; + my $getterExpression = shift; + + return "" if ($attribute->signature->type eq "NamedNodeMap"); + return "" if ($attribute->signature->type eq "NodeList"); + return "if (!$getterExpression) return; //v8::Undefined(isolate);"; +} + +sub GenerateConstructor +{ + my $interface = shift; + my $interfaceName = $interface->name; + my $wrapperType = IdlToWrapperType($interfaceName); + my $extensions = $interface->extendedAttributes; + + if ($extensions->{'Constructors'}) { + + push(@implContent, "\n void V8${interfaceName}::constructor(const v8::FunctionCallbackInfo& info) {"); + push(@implContent, <ThrowException(v8::String::NewFromUtf8(isolate, "Cannot call constructor as function")); + return; + } +END + + push(@implContent, "\n ".IdlToWrapperType($interfaceName)."* localInstance = NULL;"); + # dispatch the actual constructor + push(@implContent, "\n if (false) {\n}"); + my @variants; + foreach my $fullCons (@{$extensions->{'Constructors'}}) { + push (@variants, $fullCons); + + for (my $i = @{$fullCons}; $i > 0; $i--) { + my $variant = @{$fullCons}[$i]; + if ($variant->{'domSignature::isOptional'}) { + my $slice; + for (my $j = 0; $j < $i; $j++) { + push(@{$slice}, @{$fullCons}[$j]); + } + push (@variants, $slice); + } + } + + # sort to put most determinate signatures first + @variants = sort { + if (@{$b} != @{$a}) { + # more arguments are more determinant + @{$b} <=> @{$a}; + } else { + my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a}); + my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b}); + @bWrap <=> @aWrap; + } + } @variants; + } + foreach my $constructor (@variants) { + push(@implContent, " else if (info.Length() == " . @{$constructor}); + + for (my $i = 0; $i < @{$constructor}; $i++) { + my $type = $constructor->[$i]->{'domSignature::type'}; + AddToImplIncludes("V8".$type.".h") if (IsWrapperType($type)); + push(@implContent, " &&\n " . IdlToTypeChecker($type, "info[$i]")); + + } + push(@implContent, ") {\n"); + my $constructorArgs; + my $constructorSep = ""; + for (my $i = 0; $i < @{$constructor}; $i++) { + my $type = $constructor->[$i]->{'domSignature::type'}; + my $name = $constructor->[$i]->{'domSignature::name'}; + my ($handle, $deref) = IdlToArgHandle($type, "local".ucfirst($name), "info[$i]", $interfaceName); + $constructorArgs .= ${constructorSep}.${deref}; + $constructorSep = ", "; + push(@implContent, "\n $handle"); + + } + push(@implContent, "\n localInstance = new ".IdlToWrapperType($interfaceName)."(${constructorArgs});"); + push(@implContent, "\n\n }"); + } + push(@implContent, "\n"); + + push(@implContent, < retCtor = V8${interfaceName}::getTmpl(isolate)->GetFunction(); + v8::Persistent retObj(isolate, retCtor->NewInstance()); + + struct V8${interfaceName}::V8${interfaceName}Private* retPrivData = new V8${interfaceName}::V8${interfaceName}Private(); + retPrivData->nativeObj = localInstance; + + retObj.Get(isolate)->SetInternalField(0, V8DOM::toExternal(retPrivData)); + retObj.SetWeak(0, V8${interfaceName}::jsDestructor); + + info.GetReturnValue().Set(retObj); + return; + } +END + } + +} + +sub GenerateImplementationFunctionCallbacks +{ + my $interface = shift; + my $interfaceName = $interface->name; + my $wrapperType = IdlToWrapperType($interfaceName); + my $extensions = $interface->extendedAttributes; + + + # Generate methods for functions. + my %generated; + foreach my $function (@{$interface->functions}) { + my $name = $function->signature->name; + my $attrExt = $function->signature->extendedAttributes; + my $retType = $function->signature->type; + my $wrapperRetType = IdlToWrapperType($retType); + + next if ($attrExt->{'Custom'}); + next if (exists $generated{"${name}Callback"}); + $generated{"${name}Callback"} = 1; + + # get all functions with this name + my @sameFunctions = grep($_->signature->name eq $name, @{$interface->functions}); + + # signature + push(@implContent, <& info) { + v8::Isolate* isolate = info.GetIsolate(); +END + + # get this + push(@implContent, "\n v8::Local self = info.Holder();"); + push(@implContent, "\n struct V8${interfaceName}Private* privData = V8DOM::toClassPtr(self->GetInternalField(0));"); + + # establish all variants + my @variants; + foreach my $functionVar (@sameFunctions) { + push (@variants, $functionVar->parameters); + + for (my $i = @{$functionVar->parameters}; $i > 0; $i--) { + my $variant = @{$functionVar->parameters}[$i]; + if ($variant->{'domSignature::isOptional'}) { + my $slice; + for (my $j = 0; $j < $i; $j++) { + push(@{$slice}, @{$functionVar->parameters}[$j]); + } + push (@variants, $slice); + } + } + } + + # arguments to local handles + push(@implContent, "\n if (false) {"); + + # sort to put most determinate signatures first + @variants = sort { + if (@{$b} != @{$a}) { + # more arguments are more determinant + @{$b} <=> @{$a}; + } else { + my @aWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$a}); + my @bWrap = grep(IsWrapperType($_->{'domSignature::type'}), @{$b}); + @bWrap <=> @aWrap; + } + } @variants; + + foreach my $variant (@variants) { + my $parameterIndex = 0; + my @argList; + + push(@implContent, "\n } else if (info.Length() == " . @{$variant}); + for (my $i = 0; $i < @{$variant}; $i++) { + my $type = $variant->[$i]->{'domSignature::type'}; + push(@implContent, " &&\n " . IdlToTypeChecker($type, "info[$i]")); + } + push(@implContent, ")\n {"); + foreach my $parameter (@{$variant}) { + my $value = "info[$parameterIndex]"; + my $type = $parameter->type; + AddToImplIncludes("V8".$type.".h") if (IsWrapperType($type)); + + my ($handle, $deref) = IdlToArgHandle($parameter->type, "local".ucfirst($parameter->name), "info[${parameterIndex}]", $interfaceName); + push(@implContent, "\n ${handle}"); + push(@argList, $deref); + $parameterIndex++; + } + + # invoke native function with argument handles + my $retNativeType = IdlToNativeType($retType); + my $wrapperFunctionName = IdlToWrapperFunction($interface, $function); + if (IsWrapperType($retType)) { + push(@implContent, "\n\n ${retNativeType}* retVal = new $wrapperRetType(privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . "));\n"); + } elsif ($retNativeType eq "void") { + push(@implContent, "\n\n privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n"); + } else { + push(@implContent, "\n\n ${retNativeType} retVal = privData->nativeObj->${wrapperFunctionName}(" . join(", ", @argList) . ");\n"); + } + + # wrap return type if needed + if (IsWrapperType($retType)) { + AddToImplIncludes("V8".$retType.".h"); + + push(@implContent, < retCtor = V8${retType}::getTmpl(isolate)->GetFunction(); + v8::Persistent retObj(isolate, retCtor->NewInstance()); + + struct V8${retType}::V8${retType}Private* retPrivData = new V8${retType}::V8${retType}Private(); + retPrivData->dom = privData->dom; + retPrivData->nativeObj = retVal; + + retObj.Get(isolate)->SetInternalField(0, V8DOM::toExternal(retPrivData)); + retObj.SetWeak(0, V8${retType}::jsDestructor); + info.GetReturnValue().Set(retObj); + //return retObj; +END + } else { + my $toHandleString = NativeToHandle($retNativeType, "retVal"); + push(@implContent, "\n info.GetReturnValue().Set(${toHandleString});"); + } + } + push(@implContent, <name; + my $visibleInterfaceName = $codeGenerator->GetVisibleInterfaceName($interface); + my $v8InterfaceName = "V8$interfaceName"; + my $wrapperType = IdlToWrapperType($interfaceName); + my $extensions = $interface->extendedAttributes; + + AddToImplIncludes("V8${interfaceName}.h"); + + # Find the super descriptor. + my $parentClass = ""; + my $parentClassTemplate = ""; + foreach (@{$interface->parents}) { + my $parent = $_; + AddToImplIncludes("V8${parent}.h"); + $parentClass = "V8" . $parent; + last; + } + + push(@implContent, "namespace Arabica {\n"); + push(@implContent, "namespace DOM {\n\n"); + + if ($extensions->{'Constructors'}) { + GenerateConstructor($interface); + } + + GenerateImplementationAttributes($interface); + GenerateImplementationFunctionCallbacks($interface); + + + push(@implContent, < value) { + return getTmpl(v8::Isolate::GetCurrent())->HasInstance(value); + } + +} +} +END + + # We've already added the header for this file in implContentHeader, so remove + # it from implIncludes to ensure we don't #include it twice. +# delete $implIncludes{"${v8InterfaceName}.h"}; +} + +sub WriteData +{ + my $object = shift; + my $interface = shift; + my $outputDir = shift; + my $outputHeadersDir = shift; + + my $name = $interface->name; + my $prefix = FileNamePrefix; + my $headerFileName = "$outputHeadersDir/$prefix$name.h"; + my $implFileName = "$outputDir/$prefix$name.cpp"; + + # print "WriteData\n"; + # print Dumper($interface); + # exit(); + + # Update a .cpp file if the contents are changed. + my $contents = $headerTemplate; + $contents .= join "", @implContentHeader; + + my @includes = (); + my %implIncludeConditions = (); + foreach my $include (keys %implIncludes) { + my $condition = $implIncludes{$include}; + my $checkType = $include; + $checkType =~ s/\.h//; + next if $codeGenerator->IsSVGAnimatedType($checkType); + + if ($include =~ /wtf/) { + $include = "\<$include\>"; + } else { + $include = "\"$include\""; + } + + if ($condition eq 1) { + push @includes, $include; + } else { + push @{$implIncludeConditions{$condition}}, $include; + } + } + foreach my $include (sort @includes) { + $contents .= "#include $include\n"; + } + foreach my $condition (sort keys %implIncludeConditions) { + $contents .= "\n#if " . $codeGenerator->GenerateConditionalStringFromAttributeValue($condition) . "\n"; + foreach my $include (sort @{$implIncludeConditions{$condition}}) { + $contents .= "#include $include\n"; + } + $contents .= "#endif\n"; + } + + $contents .= "\n"; + $contents .= join "", @implContentDecls, @implContent; + $codeGenerator->UpdateFile($implFileName, $contents); + + %implIncludes = (); + @implContentHeader = (); + @implContentDecls = (); + @implContent = (); + + # Update a .h file if the contents are changed. + $contents = join "", @headerContent; + $codeGenerator->UpdateFile($headerFileName, $contents); + + @headerContent = (); +} + +sub IdlToV8Type +{ + my $idlType = shift; + return "v8::Integer" if ($idlType eq "unsigned short"); + return "v8::Integer" if ($idlType eq "short"); + return "v8::Integer" if ($idlType eq "unsigned long"); + return "v8::Integer" if ($idlType eq "long"); + return "v8::String" if ($idlType eq "DOMString"); + return "v8::Boolean" if ($idlType eq "boolean"); + return "v8::Number" if ($idlType eq "double"); + die($idlType); +} + +sub IdlToNativeType +{ + my $idlType = shift; + + return IdlToWrapperType($idlType) if (IsWrapperType($idlType)); + + return "std::string" if ($idlType eq "DOMString"); + return "bool" if ($idlType eq "boolean"); + return "short" if ($idlType eq "short"); + return "long" if ($idlType eq "long"); + return "unsigned short" if ($idlType eq "unsigned short"); + return "unsigned long" if ($idlType eq "unsigned long"); + return "void" if ($idlType eq "void"); + return "char" if ($idlType eq "byte"); + return "unsigned char" if ($idlType eq "octet"); + return "double" if ($idlType eq "double"); + return "float" if ($idlType eq "float"); + die(${idlType}); +} + +sub NativeToHandle +{ + my $nativeType = shift; + my $nativeName = shift; + + return ("v8::Boolean::New(isolate, ${nativeName})") if ($nativeType eq "bool"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "double"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "double"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "float"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "short"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "char"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "unsigned short"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "unsigned long"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "unsigned char"); + return ("v8::Number::New(isolate, ${nativeName})") if ($nativeType eq "long"); + return ("v8::String::NewFromUtf8(isolate, ${nativeName}.c_str())") if ($nativeType eq "std::string"); + return ("v8::Undefined(isolate)") if ($nativeType eq "void"); + + die($nativeType); +} + +sub IdlToWrapperType +{ + my $idlType = shift; + return "Arabica::XPath::XPathValue" if ($idlType eq "XPathResult"); + return "Arabica::XPath::NodeSet" if ($idlType eq "NodeSet"); + return "Arabica::DOM::Node" if ($idlType eq "Node"); + return "Arabica::DOM::Element" if ($idlType eq "Element"); + return "uscxml::Event" if ($idlType eq "SCXMLEvent"); + return "uscxml::Storage" if ($idlType eq "Storage"); + return "uscxml::ArrayBuffer" if ($idlType eq "ArrayBuffer"); + return "uscxml::ArrayBufferView" if ($idlType eq "ArrayBufferView"); + return "uscxml::Int8Array" if ($idlType eq "Int8Array"); + return "uscxml::Uint8Array" if ($idlType eq "Uint8Array"); + return "uscxml::Uint8ClampedArray" if ($idlType eq "Uint8ClampedArray"); + return "uscxml::Int16Array" if ($idlType eq "Int16Array"); + return "uscxml::Uint16Array" if ($idlType eq "Uint16Array"); + return "uscxml::Int32Array" if ($idlType eq "Int32Array"); + return "uscxml::Uint32Array" if ($idlType eq "Uint32Array"); + return "uscxml::Float32Array" if ($idlType eq "Float32Array"); + return "uscxml::Float64Array" if ($idlType eq "Float64Array"); + return "uscxml::DataView" if ($idlType eq "DataView"); + return "Arabica::DOM::${idlType}"; +} + +sub IdlToArgHandle +{ + my $type = shift; + my $localName = shift; + my $paramName = shift; + my $thisType = shift; + + return ("v8::String::Utf8Value ${localName}(${paramName});", "*${localName}") if ($type eq "DOMString"); + return ("unsigned long ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "unsigned long"); + return ("long ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "long"); + return ("double ${localName} = ${paramName}->ToNumber()->Value();", ${localName}) if ($type eq "double"); + return ("float ${localName} = ${paramName}->ToNumber()->Value();", ${localName}) if ($type eq "float"); + return ("unsigned short ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "unsigned short"); + return ("bool ${localName} = ${paramName}->ToBoolean()->BooleanValue();", ${localName}) if ($type eq "boolean"); + return ("char ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "byte"); + return ("short ${localName} = ${paramName}->ToNumber()->Int32Value();", ${localName}) if ($type eq "short"); + return ("unsigned char ${localName} = ${paramName}->ToNumber()->Uint32Value();", ${localName}) if ($type eq "octet"); + # return ("void* ${localName} = v8::External::Unwrap(${paramName}->ToObject()->GetInternalField(0));", ${localName}) if ($type eq "any"); + return ("void* ${localName} = v8::Handle::Cast(${paramName}->ToObject()->GetInternalField(0))->Value();", ${localName}) if ($type eq "any"); + return ("std::vector ${localName};\nv8::Handle ${localName}Array = v8::Array::New(isolate, v8::Array::Cast(*info[0])->Length());\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInteger()->Value());\n}", "${localName}") if ($type eq "long[]"); + return ("std::vector ${localName};\nv8::Handle ${localName}Array = v8::Array::New(isolate, v8::Array::Cast(*info[0])->Length());\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "float[]"); + return ("std::vector ${localName};\nv8::Handle ${localName}Array = v8::Array::New(isolate, v8::Array::Cast(*info[0])->Length());\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToNumber()->Value());\n}", "${localName}") if ($type eq "double[]"); + return ("std::vector ${localName};\nv8::Handle ${localName}Array = v8::Array::New(isolate, v8::Array::Cast(*info[0])->Length());\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "byte[]"); + return ("std::vector ${localName};\nv8::Handle ${localName}Array = v8::Array::New(isolate, v8::Array::Cast(*info[0])->Length());\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToInt32()->Value());\n}", "${localName}") if ($type eq "short[]"); + return ("std::vector ${localName};\nv8::Handle ${localName}Array = v8::Array::New(isolate, v8::Array::Cast(*info[0])->Length());\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned short[]"); + return ("std::vector ${localName};\nv8::Handle ${localName}Array = v8::Array::New(isolate, v8::Array::Cast(*info[0])->Length());\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "unsigned long[]"); + return ("std::vector ${localName};\nv8::Handle ${localName}Array = v8::Array::New(isolate, v8::Array::Cast(*info[0])->Length());\nfor (int i = 0; i < ${localName}Array->Length(); i++) {\n ${localName}.push_back(${localName}Array->Get(i)->ToUint32()->Value());\n}", "${localName}") if ($type eq "octet[]"); + + if (IsWrapperType($type)) { + my $wrapperType = IdlToWrapperType($type); + if ($type =~ /.*Array$/ or $type =~ /^ArrayBuffer.*/) { + return ("${wrapperType}* ${localName} = V8DOM::toClassPtr(${paramName}->ToObject()->GetInternalField(0))->nativeObj;", "${localName}"); + } + + return ("${wrapperType}* ${localName} = V8DOM::toClassPtr(${paramName}->ToObject()->GetInternalField(0))->nativeObj;", "*${localName}"); + } + + print $type."\n"; + die(); +} + +sub IdlToTypeChecker +{ + my $idlType = shift; + my $attr = shift; + + return $attr."->IsString()" if ($idlType eq "DOMString"); + return $attr."->IsBoolean()" if ($idlType eq "boolean"); + return $attr."->IsInt32()" if ($idlType eq "short"); + return $attr."->IsInt32()" if ($idlType eq "long"); + return $attr."->IsArray()" if ($idlType eq "long[]"); + return $attr."->IsUint32()" if ($idlType eq "unsigned short"); + return $attr."->IsUint32()" if ($idlType eq "unsigned long"); + return $attr."->IsInt32()" if ($idlType eq "byte"); + return $attr."->IsUint32()" if ($idlType eq "octet"); + return $attr."->IsNumber()" if ($idlType eq "double"); + return $attr."->IsArray()" if ($idlType eq "double[]"); + return $attr."->IsNumber()" if ($idlType eq "float"); + return $attr."->IsArray()" if ($idlType eq "float[]"); + return $attr."->IsArray()" if ($idlType eq "short[]"); + return $attr."->IsArray()" if ($idlType eq "unsigned short[]"); + return $attr."->IsArray()" if ($idlType eq "unsigned long[]"); + return $attr."->IsArray()" if ($idlType eq "byte[]"); + return $attr."->IsArray()" if ($idlType eq "octet[]"); + return "true" if ($idlType eq "any"); + + return $attr."->IsObject() && V8".$idlType."::hasInstance(".$attr.")" if (IsWrapperType($idlType)); + + print $idlType."\n"; + die(); + +} + +sub IdlToWrapperAttrGetter +{ + my $interface = shift; + my $attribute = shift; + + return $attribute->signature->name if ($interface->name eq "NodeSet" && $attribute->signature->name eq "size"); + return $attribute->signature->name if ($interface->name eq "NodeSet" && $attribute->signature->name eq "empty"); + return "asString" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "stringValue"); + return "asBool" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "booleanValue"); + return "asNumber" if ($interface->name eq "XPathResult" && $attribute->signature->name eq "numberValue"); + + return "get" . ucfirst($attribute->signature->name); +} + +sub IdlToWrapperFunction +{ + my $interface = shift; + my $function = shift; + + # if ($interface->name eq "NodeSet" && $function->signature->name eq "toDocumentOrder") { + # print Dumper($interface); + # print Dumper($function); + # } + + return "to_document_order" if ($interface->name eq "NodeSet" && $function->signature->name eq "toDocumentOrder"); + + return $function->signature->name; + +} + +sub IdlToWrapperAttrSetter +{ + my $idlAttr = shift; + return "set" . ucfirst($idlAttr); +} + + +sub IsReadonly +{ + my $attribute = shift; + my $attrExt = $attribute->signature->extendedAttributes; + return ($attribute->type =~ /readonly/ || $attrExt->{"V8ReadOnly"}) && !$attrExt->{"Replaceable"}; +} + + +my %non_wrapper_types = ( + 'CompareHow' => 1, + 'DOMObject' => 1, + 'DOMString' => 1, + 'DOMString[]' => 1, + 'DOMTimeStamp' => 1, + 'Date' => 1, + 'Dictionary' => 1, + 'EventListener' => 1, + # FIXME: When EventTarget is an interface and not a mixin, fix this so that + # EventTarget is treated as a wrapper type. + 'EventTarget' => 1, + 'IDBKey' => 1, + 'JSObject' => 1, + 'MediaQueryListListener' => 1, + 'NodeFilter' => 1, + 'any' => 1, + 'boolean' => 1, + 'double' => 1, + 'float' => 1, + 'int' => 1, + 'long long' => 1, + 'long' => 1, + 'long[]' => 1, + 'short' => 1, + 'short[]' => 1, + 'void' => 1, + 'byte' => 1, + 'byte[]' => 1, + 'octet' => 1, + 'char' => 1, + 'float[]' => 1, + 'float' => 1, + 'double[]' => 1, + 'octet[]' => 1, + 'double' => 1, + 'unsigned int' => 1, + 'unsigned long long' => 1, + 'unsigned long' => 1, + 'unsigned long[]' => 1, + 'unsigned short' => 1, + 'unsigned short[]' => 1 +); + +sub IsWrapperType +{ + my $type = shift; + return !($non_wrapper_types{$type}); +} + +sub GenerateHeaderContentHeader +{ + my $interface = shift; + my $v8InterfaceName = "V8" . $interface->name; + my $conditionalString = $codeGenerator->GenerateConditionalString($interface); + + my @headerContentHeader = split("\r", $headerTemplate); + + push(@headerContentHeader, "\n#if ${conditionalString}\n") if $conditionalString; + push(@headerContentHeader, "\n#ifndef ${v8InterfaceName}" . "_h"); + push(@headerContentHeader, "\n#define ${v8InterfaceName}" . "_h\n\n"); + return @headerContentHeader; +} + +1; diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index f27d93e..c65c8f7 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -561,7 +561,7 @@ public: virtual ~Interpreter() {}; operator bool() const { - return (_impl && _impl->_state != USCXML_DESTROYED); + return (!!_impl && _impl->_state != USCXML_DESTROYED); } bool operator< (const Interpreter& other) const { return _impl < other._impl; diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h index 1da2e7f..dacf0db 100644 --- a/src/uscxml/URL.h +++ b/src/uscxml/URL.h @@ -161,7 +161,7 @@ public: virtual ~URL() {}; operator bool() const { - return _impl; + return !!_impl; } bool operator< (const URL& other) const { return _impl < other._impl; diff --git a/src/uscxml/messages/Blob.h b/src/uscxml/messages/Blob.h index 0c20f95..835c73a 100644 --- a/src/uscxml/messages/Blob.h +++ b/src/uscxml/messages/Blob.h @@ -77,7 +77,7 @@ public: virtual ~Blob() {}; operator bool() const { - return _impl; + return !!_impl; } bool operator< (const Blob& other) const { return _impl < other._impl; diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h index 1a64d28..5cbd0c8 100644 --- a/src/uscxml/plugins/DataModel.h +++ b/src/uscxml/plugins/DataModel.h @@ -139,7 +139,7 @@ public: virtual ~DataModel() {}; operator bool() const { - return _impl; + return !!_impl; } bool operator< (const DataModel& other) const { return _impl < other._impl; diff --git a/src/uscxml/plugins/ExecutableContent.h b/src/uscxml/plugins/ExecutableContent.h index 6916b5f..6df197c 100644 --- a/src/uscxml/plugins/ExecutableContent.h +++ b/src/uscxml/plugins/ExecutableContent.h @@ -60,7 +60,7 @@ public: virtual ~ExecutableContent() {}; operator bool() const { - return _impl; + return !!_impl; } bool operator< (const ExecutableContent& other) const { return _impl < other._impl; diff --git a/src/uscxml/plugins/IOProcessor.h b/src/uscxml/plugins/IOProcessor.h index 79f759b..c770719 100644 --- a/src/uscxml/plugins/IOProcessor.h +++ b/src/uscxml/plugins/IOProcessor.h @@ -42,7 +42,7 @@ public: virtual ~IOProcessor() {}; operator bool() const { - return _impl; + return !!_impl; } bool operator< (const IOProcessor& other) const { return _impl < other._impl; diff --git a/src/uscxml/plugins/Invoker.h b/src/uscxml/plugins/Invoker.h index dd3d66d..b9b767b 100644 --- a/src/uscxml/plugins/Invoker.h +++ b/src/uscxml/plugins/Invoker.h @@ -50,7 +50,7 @@ public: virtual ~Invoker() {}; operator bool() const { - return _impl; + return !!_impl; } bool operator< (const Invoker& other) const { return _impl < other._impl; diff --git a/src/uscxml/plugins/datamodel/ecmascript/TypedArray.cpp b/src/uscxml/plugins/datamodel/ecmascript/TypedArray.cpp index 913d2ce..c8b73cf 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/TypedArray.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/TypedArray.cpp @@ -75,7 +75,7 @@ bool ArrayBuffer::isView(void*) { } ArrayBuffer::operator bool() { - return _blob; + return !!_blob; } ArrayBuffer ArrayBufferView::getBuffer() { diff --git a/src/uscxml/transform/Transformer.h b/src/uscxml/transform/Transformer.h index 3751c00..c8498ff 100644 --- a/src/uscxml/transform/Transformer.h +++ b/src/uscxml/transform/Transformer.h @@ -52,7 +52,7 @@ public: virtual ~Transformer() {}; operator bool() const { - return (_impl); + return !!_impl; } bool operator< (const Transformer& other) const { return _impl < other._impl; -- cgit v0.12