1 Commits

Autor SHA1 Mensagem Data
Sara Golemon 2d963c4ffb 2.2.0 release 2013-10-16 11:17:06 -07:00
2386 arquivos alterados com 101197 adições e 518730 exclusões
+9 -4
Ver Arquivo
@@ -1,5 +1,10 @@
*.[oad]
*.hhbc
/bin*-g
/bin*-O
/bin/*.so
/bin/hphp_options
/bin/systemlib.php
.mkdir
hphp.log
@@ -36,8 +41,6 @@ hphp.log
/hphp/runtime/ext/*.ext_hhvm.h
/hphp/runtime/ext/*/*.ext_hhvm.cpp
/hphp/runtime/ext/*/*.ext_hhvm.h
/hphp/runtime/ext/*/*/*.ext_hhvm.h
/hphp/runtime/ext/*/*/*.ext_hhvm.cpp
/hphp/runtime/ext_zend_compat/*/*.ext_hhvm.cpp
/hphp/runtime/ext_zend_compat/*/*.ext_hhvm.h
/hphp/runtime/ext_zend_compat/*/*/*.ext_hhvm.cpp
@@ -52,6 +55,10 @@ hphp.log
/hphp/ffi/java/classes
/hphp/ffi/java/hphp_ffi_java.h
# Ignore all makefiles generated for fbcode's third-party repo
/bin/*.mk
!/bin/run.mk
CMakeFiles
CMakeCache.txt
cmake_install.cmake
@@ -61,8 +68,6 @@ install_manifest.txt
/hphp/TAGS
/hphp/third_party/libzip/libzip.dylib
# Generated makefiles
/hphp/runtime/ext_hhvm/Makefile
/hphp/test/Makefile
-3
Ver Arquivo
@@ -1,3 +0,0 @@
[submodule "hphp/submodules/folly"]
path = hphp/submodules/folly
url = git://github.com/facebook/folly.git
-1
Ver Arquivo
@@ -23,5 +23,4 @@ env:
script: hphp/hhvm/hhvm hphp/test/run $TEST_RUN_MODE
notifications:
email: false
irc: "chat.freenode.net#hhvm"
+1 -1
Ver Arquivo
@@ -21,7 +21,7 @@ CHECK_C_SOURCE_RUNS("#include <dlfcn.h>
void testfunc() {}
int main() {
testfunc();
return dyslm(0, \"_testfunc\") != (void*)0;
return dyslm(0, "_testfunc") != (void*)0;
}" LIBDL_NEEDS_UNDERSCORE)
mark_as_advanced(LIBDL_INCLUDE_DIRS LIBDL_LIBRARIES LIBDL_NEEDS_UNDERSCORE)
-31
Ver Arquivo
@@ -1,31 +0,0 @@
# folly-config.h is a generated file from autotools
# We need to do the equivalent checks here and use
# add_definitions as needed
add_definitions(-DFOLLY_NO_CONFIG=1)
INCLUDE(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("
extern \"C\" void (*test_ifunc(void))() { return 0; }
void func() __attribute__((ifunc(\"test_ifunc\")));
" FOLLY_IFUNC)
if (FOLLY_IFUNC)
add_definitions("-DHAVE_IFUNC=1")
endif()
set(CMAKE_REQUIRED_LIBRARIES rt)
CHECK_CXX_SOURCE_COMPILES("#include <time.h>
int main() {
clock_gettime((clockid_t)0, NULL);
return 0;
}" HAVE_CLOCK_GETTIME)
if (HAVE_CLOCK_GETTIME)
add_definitions("-DFOLLY_HAVE_CLOCK_GETTIME=1")
endif()
set(CMAKE_REQUIRED_LIBRARIES)
find_path(FEATURES_H_INCLUDE_DIR NAMES features.h)
if (FEATURES_H_INCLUDE_DIR)
include_directories("${FEATURES_H_INCLUDE_DIR}")
add_definitions("-DFOLLY_HAVE_FEATURES_H=1")
endif()
+17 -8
Ver Arquivo
@@ -1,5 +1,14 @@
if(CMAKE_COMPILER_IS_GNUCC)
INCLUDE(CheckCSourceCompiles)
CHECK_C_SOURCE_COMPILES("#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION < 40600
#error Need GCC 4.6.0+
#endif
int main() { return 0; }" HAVE_GCC_46)
if(NOT HAVE_GCC_46)
message(FATAL_ERROR "Need at least GCC 4.6")
endif()
CHECK_C_SOURCE_COMPILES("#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION < 40700
@@ -7,10 +16,6 @@ if(CMAKE_COMPILER_IS_GNUCC)
#endif
int main() { return 0; }" HAVE_GCC_47)
if (NOT HAVE_GCC_47)
message(FATAL_ERROR "Need at least GCC 4.7")
endif()
CHECK_C_SOURCE_COMPILES("#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION < 40800
#error Not GCC 4.8.0+
@@ -32,14 +37,18 @@ endif()
if($ENV{CXX} MATCHES "icpc")
set(CMAKE_C_FLAGS "-no-ipo -fp-model precise -wd584 -wd1418 -wd1918 -wd383 -wd869 -wd981 -wd424 -wd1419 -wd444 -wd271 -wd2259 -wd1572 -wd1599 -wd82 -wd177 -wd593 -w")
set(CMAKE_CXX_FLAGS "-no-ipo -fp-model precise -wd584 -wd1418 -wd1918 -wd383 -wd869 -wd981 -wd424 -wd1419 -wd444 -wd271 -wd2259 -wd1572 -wd1599 -wd82 -wd177 -wd593 -fno-omit-frame-pointer -ftemplate-depth-180 -Wall -Woverloaded-virtual -Wno-deprecated -w1 -Wno-strict-aliasing -Wno-write-strings -Wno-invalid-offsetof -fno-operator-names")
set(CMAKE_CXX_FLAGS "-no-ipo -fp-model precise -wd584 -wd1418 -wd1918 -wd383 -wd869 -wd981 -wd424 -wd1419 -wd444 -wd271 -wd2259 -wd1572 -wd1599 -wd82 -wd177 -wd593 -fno-omit-frame-pointer -ftemplate-depth-120 -Wall -Woverloaded-virtual -Wno-deprecated -w1 -Wno-strict-aliasing -Wno-write-strings -Wno-invalid-offsetof -fno-operator-names")
else()
set(GNUCC_48_OPT "")
set(GNUCC_UNINIT_OPT "")
if(HAVE_GCC_47)
set(GNUCC_UNINIT_OPT "-Wno-maybe-uninitialized")
endif()
set(GNUCC_LOCAL_TYPEDEF_OPT "")
if(HAVE_GCC_48)
set(GNUCC_48_OPT "-Wno-unused-local-typedefs -fno-canonical-system-headers -Wno-deprecated-declarations")
set(GNUCC_LOCAL_TYPEDEF_OPT "-Wno-unused-local-typedefs")
endif()
set(CMAKE_C_FLAGS "-w")
set(CMAKE_CXX_FLAGS "-fno-gcse -fno-omit-frame-pointer -ftemplate-depth-180 -Wall -Woverloaded-virtual -Wno-deprecated -Wno-strict-aliasing -Wno-write-strings -Wno-invalid-offsetof -fno-operator-names -Wno-error=array-bounds -Wno-error=switch -std=gnu++11 -Werror=format-security -Wno-unused-result -Wno-sign-compare -Wno-attributes -Wno-maybe-uninitialized ${GNUCC_48_OPT}")
set(CMAKE_CXX_FLAGS "-fno-gcse -fno-omit-frame-pointer -ftemplate-depth-120 -Wall -Woverloaded-virtual -Wno-deprecated -Wno-strict-aliasing -Wno-write-strings -Wno-invalid-offsetof -fno-operator-names -Wno-error=array-bounds -Wno-error=switch -std=gnu++0x -Werror=format-security -Wno-unused-result -Wno-sign-compare -Wno-attributes ${GNUCC_UNINIT_OPT} ${GNUCC_LOCAL_TYPEDEF_OPT}")
endif()
if(CMAKE_COMPILER_IS_GNUCC)
+16 -18
Ver Arquivo
@@ -31,11 +31,6 @@ endif()
find_package(Boost 1.48.0 COMPONENTS system program_options filesystem regex REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
# Boost 1.49 supports a better flat_multimap, but 1.48 is good enough
if (Boost_VERSION GREATER 104899)
add_definitions("-DHAVE_BOOST1_49")
endif()
# features.h
FIND_PATH(FEATURES_HEADER features.h)
@@ -90,10 +85,13 @@ include_directories(${LIBEVENT_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES "${LIBEVENT_LIB}")
CHECK_FUNCTION_EXISTS("evhttp_bind_socket_with_fd" HAVE_CUSTOM_LIBEVENT)
if(HAVE_CUSTOM_LIBEVENT)
message("Using custom LIBEVENT")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_CUSTOM_LIBEVENT")
endif()
if (NOT HAVE_CUSTOM_LIBEVENT)
unset(HAVE_CUSTOM_LIBEVENT CACHE)
unset(LIBEVENT_INCLUDE_DIR CACHE)
unset(LIBEVENT_LIB CACHE)
unset(LibEvent_FOUND CACHE)
message(FATAL_ERROR "Custom libevent is required with HipHop patches")
endif ()
set(CMAKE_REQUIRED_LIBRARIES)
# GD checks
@@ -138,7 +136,6 @@ include_directories("${HPHP_HOME}/hphp/third_party/libmbfl/filter")
include_directories("${HPHP_HOME}/hphp/third_party/lz4")
include_directories("${HPHP_HOME}/hphp/third_party/double-conversion/src")
include_directories("${HPHP_HOME}/hphp/third_party/folly")
include_directories("${HPHP_HOME}/hphp/third_party/libzip")
# ICU
find_package(ICU REQUIRED)
@@ -305,17 +302,19 @@ if (NOT RECENT_CCLIENT)
message(FATAL_ERROR "Your version of c-client is too old, you need 2007")
endif()
find_package(Libpam)
if (PAM_INCLUDE_PATH)
include_directories(${PAM_INCLUDE_PATH})
else()
add_definitions(-DSKIP_IMAP_GSS=1)
endif()
CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.h" auth_gss CCLIENT_NEEDS_PAM)
if (EXISTS "${CCLIENT_INCLUDE_PATH}/linkage.c")
CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/linkage.c" ssl_onceonlyinit CCLIENT_HAS_SSL)
endif()
if (CCLIENT_NEEDS_PAM)
find_package(Libpam REQUIRED)
include_directories(${PAM_INCLUDE_PATH})
else()
add_definitions(-DSKIP_IMAP_GSS=1)
endif()
if (NOT CCLIENT_HAS_SSL)
add_definitions(-DSKIP_IMAP_SSL=1)
endif()
@@ -463,7 +462,6 @@ endif()
target_link_libraries(${target} lz4)
target_link_libraries(${target} double-conversion)
target_link_libraries(${target} folly)
target_link_libraries(${target} zip_static)
target_link_libraries(${target} afdt)
target_link_libraries(${target} mbfl)
@@ -477,7 +475,7 @@ endif()
target_link_libraries(${target} ${NCURSES_LIBRARY})
target_link_libraries(${target} ${CCLIENT_LIBRARY})
if (PAM_LIBRARY)
if (CCLIENT_NEEDS_PAM)
target_link_libraries(${target} ${PAM_LIBRARY})
endif()
+5 -40
Ver Arquivo
@@ -68,52 +68,17 @@ macro(MYSQL_SOCKET_SEARCH)
endif()
endmacro()
function(embed_systemlib TARGET DEST SOURCE SECTNAME)
function(embed_systemlib TARGET DEST SOURCE)
if (APPLE)
target_link_libraries(${TARGET} -Wl,-sectcreate,__text,${SECTNAME},${SOURCE})
target_link_libraries(${TARGET} -Wl,-sectcreate,__text,systemlib,${SOURCE})
else()
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND "objcopy"
ARGS "--add-section" "${SECTNAME}=${SOURCE}" ${DEST}
COMMENT "Embedding ${SOURCE} in ${TARGET} as ${SECTNAME}")
ARGS "--add-section" "systemlib=${SOURCE}" ${DEST}
COMMENT "Embedding systemlib.php in ${TARGET}")
endif()
# Add the systemlib file to the "LINK_DEPENDS" for the systemlib, this will cause it
# to be relinked and the systemlib re-embedded
set_property(TARGET ${TARGET} APPEND PROPERTY LINK_DEPENDS ${SOURCE})
endfunction(embed_systemlib)
function(embed_all_systemlibs TARGET DEST)
embed_systemlib(${TARGET} ${DEST} ${HPHP_HOME}/hphp/system/systemlib.php systemlib)
auto_sources(SYSTEMLIBS "ext_*.php" "RECURSE" "${HPHP_HOME}/hphp/runtime")
foreach(SLIB ${SYSTEMLIBS})
get_filename_component(SLIB_BN ${SLIB} "NAME_WE")
string(LENGTH ${SLIB_BN} SLIB_BN_LEN)
math(EXPR SLIB_BN_REL_LEN "${SLIB_BN_LEN} - 4")
string(SUBSTRING ${SLIB_BN} 4 ${SLIB_BN_REL_LEN} SLIB_EXTNAME)
string(MD5 SLIB_HASH_NAME ${SLIB_EXTNAME})
string(SUBSTRING ${SLIB_HASH_NAME} 0 12 SLIB_HASH_NAME_SHORT)
embed_systemlib(${TARGET} ${DEST} ${SLIB} "ext.${SLIB_HASH_NAME_SHORT}")
endforeach()
endfunction(embed_all_systemlibs)
# Custom install function that doesn't relink, instead it uses chrpath to change it, if
# it's available, otherwise, it leaves the chrpath alone
function(HHVM_INSTALL TARGET DEST)
get_target_property(LOC ${TARGET} LOCATION)
get_target_property(TY ${TARGET} TYPE)
if (FOUND_CHRPATH)
get_target_property(RPATH ${TARGET} INSTALL_RPATH)
if (NOT RPATH STREQUAL "RPATH-NOTFOUND")
if (RPATH STREQUAL "")
install(CODE "execute_process(COMMAND \"${CHRPATH}\" \"-d\" \"${LOC}\" ERROR_QUIET)")
else()
install(CODE "execute_process(COMMAND \"${CHRPATH}\" \"-r\" \"${RPATH}\" \"${LOC}\" ERROR_QUIET)")
endif()
endif()
endif()
install(CODE "FILE(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${DEST}\" TYPE ${TY} FILES \"${LOC}\")")
endfunction(HHVM_INSTALL)
function(HHVM_EXTENSION EXTNAME)
list(REMOVE_AT ARGV 0)
add_library(${EXTNAME} SHARED ${ARGV})
@@ -122,5 +87,5 @@ function(HHVM_EXTENSION EXTNAME)
endfunction()
function(HHVM_SYSTEMLIB EXTNAME SOURCE_FILE)
embed_systemlib(${EXTNAME} "${EXTNAME}.so" ${SOURCE_FILE} systemlib)
embed_systemlib(${EXTNAME} "${EXTNAME}.so" ${SOURCE_FILE})
endfunction()
+2 -30
Ver Arquivo
@@ -1,18 +1,9 @@
include(Options)
# Do this until cmake has a define for ARMv8
INCLUDE(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("
#ifndef __AARCH64EL__
#error Not ARMv8
#endif
int main() { return 0; }" IS_AARCH64)
if (APPLE OR IS_AARCH64)
if (APPLE)
set(HHVM_ANCHOR_SYMS -Wl,-u,_register_libevent_server)
else()
set(ENABLE_FASTCGI 1)
set(HHVM_ANCHOR_SYMS -Wl,-uregister_libevent_server,-uregister_fastcgi_server)
set(HHVM_ANCHOR_SYMS -Wl,-uregister_libevent_server)
endif()
set(HHVM_LINK_LIBRARIES
@@ -23,15 +14,9 @@ set(HHVM_LINK_LIBRARIES
hphp_parser
hphp_zend
hphp_util
hphp_hhbbc
vixl neo
${HHVM_ANCHOR_SYMS})
if(ENABLE_FASTCGI)
LIST(APPEND HHVM_LINK_LIBRARIES hphp_thrift)
LIST(APPEND HHVM_LINK_LIBRARIES hphp_proxygen)
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
@@ -40,15 +25,6 @@ IF(NOT DEFINED CMAKE_PREFIX_PATH)
message(STATUS "CMAKE_PREFIX_PATH was missing, proceeding anyway")
endif()
# Look for the chrpath tool so we can warn if it's not there
find_program(CHRPATH chrpath)
IF (CHRPATH STREQUAL "CHRPATH-NOTFOUND")
SET(FOUND_CHRPATH OFF)
message(WARNING "chrpath not found, rpath will not be stripped from installed binaries")
else()
SET(FOUND_CHRPATH ON)
endif()
LIST(APPEND CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}")
if(APPLE)
@@ -120,10 +96,6 @@ if(APPLE)
add_definitions(-DMACOSX_DEPLOYMENT_TARGET=10.6)
endif()
if(ENABLE_FASTCGI)
add_definitions(-DENABLE_FASTCGI=1)
endif ()
# enable the OSS options if we have any
add_definitions(-DHPHP_OSS=1)
+13 -13
Ver Arquivo
@@ -1,46 +1,46 @@
# HHVM [![Build Status](https://travis-ci.org/facebook/hhvm.png?branch=master)](https://travis-ci.org/facebook/hhvm)
# HipHop VM for PHP [![Build Status](https://travis-ci.org/facebook/hiphop-php.png?branch=master)](https://travis-ci.org/facebook/hiphop-php)
HHVM (aka the HipHop Virtual Machine) is a new open-source virtual machine designed for executing programs written in PHP. HHVM uses a just-in-time compilation approach to achieve superior performance while maintaining the flexibility that PHP developers are accustomed to. To date, HHVM (and its precedessor HPHPc before it) has realized over a 9x increase in web request throughput and over a 5x reduction in memory consumption for Facebook compared with the Zend PHP 5.2 engine + APC.
HipHop VM (HHVM) is a new open-source virtual machine designed for executing programs written in PHP. HHVM uses a just-in-time compilation approach to achieve superior performance while maintaining the flexibility that PHP developers are accustomed to. HipHop VM (and before it HPHPc) has realized > 5x increase in throughput for Facebook compared with Zend PHP 5.2.
HHVM can be run as a standalone webserver (i.e. without the Apache webserver and the "modphp" extension). HHVM can also be used together with a FastCGI-based webserver, and work is in progress to make HHVM work smoothly with Apache.
HipHop is most commonly run as a standalone server, replacing both Apache and modphp.
## FAQ
Our [FAQ](https://github.com/facebook/hhvm/wiki/FAQ) has answers to many common questions about HHVM, from [general questions](https://github.com/facebook/hhvm/wiki/FAQ#general) to questions geared towards those that want to [use](https://github.com/facebook/hhvm/wiki/FAQ#users) or [contribute](https://github.com/facebook/hhvm/wiki/FAQ#contributors) to HHVM.
Our [FAQ](https://github.com/facebook/hiphop-php/wiki/FAQ) has answers to many common questions about HHVM, from [general questions](https://github.com/facebook/hiphop-php/wiki/FAQ#general) to questions geared towards those that want to [use](https://github.com/facebook/hiphop-php/wiki/FAQ#users) or [contribute](https://github.com/facebook/hiphop-php/wiki/FAQ#contributors) to HHVM.
## Installing
You can install a [prebuilt package](https://github.com/facebook/hhvm/wiki#installing-pre-built-packages-for-hhvm) or [compile from source](https://github.com/facebook/hhvm/wiki#building-hhvm).
You can install a [prebuilt package](https://github.com/facebook/hiphop-php/wiki#installing-pre-built-packages-for-hhvm) or [compile from source](https://github.com/facebook/hiphop-php/wiki#building-hhvm).
## Running
You can run standalone programs just by passing them to hhvm: `hhvm my_script.php`.
HHVM bundles in a webserver. So if you want to run on port 80 in the current directory:
HipHop bundles in a webserver. So if you want to run on port 80 in the current directory:
```
sudo hhvm -m server
```
For anything more complicated, you'll want to make a [config.hdf](https://github.com/facebook/hhvm/wiki/Runtime-options#server) and run `sudo hhvm -m server -c config.hdf`.
For anything more complicated, you'll want to make a [config.hdf](https://github.com/facebook/hiphop-php/wiki/Runtime-options#server) and run `sudo hhvm -m server -c config.hdf`.
## Contributing
We'd love to have your help in making HHVM better.
We'd love to have your help in making HipHop better.
Before changes can be accepted a [Contributor License Agreement](http://developers.facebook.com/opensource/cla) ([pdf](https://github.com/facebook/hhvm/raw/master/hphp/doc/FB_Individual_CLA.pdf) - print, sign, scan, link) must be signed.
Before changes can be accepted a [Contributor License Agreement](http://developers.facebook.com/opensource/cla) ([pdf](https://github.com/facebook/hiphop-php/raw/master/hphp/doc/FB_Individual_CLA.pdf) - print, sign, scan, link) must be signed.
If you run into problems, please open an [issue](http://github.com/facebook/hhvm/issues), or better yet, [fork us and send a pull request](https://github.com/facebook/hhvm/pulls). Join us on [#hhvm on freenode](http://webchat.freenode.net/?channels=hhvm).
If you run into problems, please open an [issue](http://github.com/facebook/hiphop-php/issues), or better yet, [fork us and send a pull request](https://github.com/facebook/hiphop-php/pulls). Join us on [#hhvm on freenode](http://webchat.freenode.net/?channels=hhvm).
If you want to help but don't know where to start, try fixing some of the [Zend tests that don't pass](hphp/test/zend/bad). You can run them with [hphp/test/run](hphp/test/run). When they work, move them to [zend/good](hphp/test/zend/good) and send a pull request.
All the open issues tagged [Zend incompatibility](https://github.com/facebook/hhvm/issues?labels=zend+incompatibility&page=1&state=open) are real issues reported by the community in existing PHP code and [frameworks](https://github.com/facebook/hhvm/wiki/OSS-PHP-Frameworks-Unit-Testing:-General) that could use some attention. Please add appropriate test cases as you make changes; see [here](hphp/test) for more information. Travis-CI is integrated with this GitHub project and will provide test results automatically on all pulls.
All the open issues tagged [Zend incompatibility](https://github.com/facebook/hiphop-php/issues?labels=zend+incompatibility&page=1&state=open) are real issues reported by the community in existing PHP code and [frameworks](https://github.com/facebook/hiphop-php/wiki/OSS-PHP-Frameworks-Unit-Testing:-General) that could use some attention. Please add appropriate test cases as you make changes; see [here](hphp/test) for more information. Travis-CI is integrated with this GitHub project and will provide test results automatically on all pulls.
## License
HHVM is licensed under the PHP and Zend licenses except as otherwise noted.
HipHop VM is licensed under the PHP and Zend licenses except as otherwise noted.
## Reporting Crashes
See [Reporting Crashes](https://github.com/facebook/hhvm/wiki/Reporting-Crashes) for helpful tips on how to report crashes in an actionable manner.
See [Reporting Crashes](https://github.com/facebook/hiphop-php/wiki/Reporting-Crashes) for helpful tips on how to report crashes in an actionable manner.
+1
Ver Arquivo
@@ -0,0 +1 @@
This file just exists to keep the bin/ directory in git.
+4 -27
Ver Arquivo
@@ -22,14 +22,10 @@ fi
export CMAKE_PREFIX_PATH=`/bin/pwd`/..
export HPHP_HOME=`/bin/pwd`
# install python-software-properties before trying to add a PPA
sudo apt-get -y update
sudo apt-get install -y python-software-properties
# install apt-fast to speedup later dependency installation
sudo add-apt-repository -y ppa:apt-fast/stable
sudo apt-get -y update
sudo apt-get -y install apt-fast
sudo apt-get update
sudo apt-get install apt-fast
# install the actual dependencies
sudo apt-fast -y update
@@ -37,8 +33,8 @@ sudo apt-fast -y install git-core cmake g++ libboost1.48-dev libmysqlclient-dev
libxml2-dev libmcrypt-dev libicu-dev openssl build-essential binutils-dev \
libcap-dev libgd2-xpm-dev zlib1g-dev libtbb-dev libonig-dev libpcre3-dev \
autoconf libtool libcurl4-openssl-dev libboost-regex1.48-dev libboost-system1.48-dev \
libboost-program-options1.48-dev libboost-filesystem1.48-dev libboost-thread1.48-dev \
wget memcached libreadline-dev libncurses-dev libmemcached-dev libbz2-dev \
libboost-program-options1.48-dev libboost-filesystem1.48-dev wget memcached \
libreadline-dev libncurses-dev libmemcached-dev libbz2-dev \
libc-client2007e-dev php5-mcrypt php5-imagick libgoogle-perftools-dev \
libcloog-ppl0 libelf-dev libdwarf-dev libunwind7-dev subversion &
@@ -47,9 +43,6 @@ git clone git://github.com/bagder/curl.git --quiet &
svn checkout http://google-glog.googlecode.com/svn/trunk/ google-glog --quiet &
wget http://www.canonware.com/download/jemalloc/jemalloc-3.0.0.tar.bz2 --quiet &
# init submodules
git submodule update --init
# wait until all background processes finished
FAIL=0
@@ -67,22 +60,6 @@ else
exit 100
fi
# Leave this install till after the main parallel package install above
# since it adds a non-12.04 package repo and we don't want to
# pull EVERYTHING in, just the newer gcc compiler (and toolchain)
GCC_VER=4.7
if [ "x${TRAVIS}" != "x" ]; then
GCC_VER=4.8
fi
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get -y update
sudo apt-get -y install gcc-${GCC_VER} g++-${GCC_VER}
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_VER} 60 \
--slave /usr/bin/g++ g++ /usr/bin/g++-${GCC_VER}
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 40 \
--slave /usr/bin/g++ g++ /usr/bin/g++-4.6
sudo update-alternatives --set gcc /usr/bin/gcc-${GCC_VER}
# libevent
cd libevent
git checkout release-1.4.14b-stable
-26
Ver Arquivo
@@ -1,26 +0,0 @@
# HHVM build results
*.hhbc
*.[oa]
/hhvm/hhvm
/hhvm/hphp
# vim swapfiles
.*.swp
.*.swo
# tags files
*/tags
*/TAGS
# logs
*.log
# git patch files
*.diff
# OS X
.DS_Store
._.DS_Store
# gdb
.gdb_history
+46 -11
Ver Arquivo
@@ -16,14 +16,44 @@
#
include(HPHPSetup)
include(FollySetup)
# HHVM Build
SET(USE_HHVM TRUE)
SET(ENV{HHVM} 1)
ADD_DEFINITIONS("-DHHVM -DHHVM_BINARY=1 -DHHVM_PATH=\\\"${HPHP_HOME}/hphp/hhvm/hhvm\\\"")
add_subdirectory(tools/bootstrap)
set(RECURSIVE_SOURCE_SUBDIRS runtime/base runtime/debugger runtime/eval runtime/ext runtime/server runtime/vm)
foreach (dir ${RECURSIVE_SOURCE_SUBDIRS})
auto_sources(files "*.cpp" "RECURSE" "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
list(APPEND CXX_SOURCES ${files})
auto_sources(files "*.c" "RECURSE" "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
list(APPEND C_SOURCES ${files})
auto_sources(files "*.S" "RECURSE" "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
list(APPEND ASM_SOURCES ${files})
endforeach(dir ${RECURSIVE_SOURCE_SUBDIRS})
if(NOT LINUX)
add_definitions(-DNO_HARDWARE_COUNTERS)
list(REMOVE_ITEM CXX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/runtime/vm/debug/elfwriter.cpp)
endif()
# Not working with off-the-shelf libevent
list(REMOVE_ITEM CXX_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/runtime/server/server-name-indication.cpp")
# remove ext_hhvm, and anything in a test folder
foreach (file ${CXX_SOURCES})
if (${file} MATCHES "ext_hhvm")
list(REMOVE_ITEM CXX_SOURCES ${file})
endif()
if (${file} MATCHES "/test/")
list(REMOVE_ITEM CXX_SOURCES ${file})
endif()
endforeach(file ${CXX_SOURCES})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
add_subdirectory(third_party/libafdt)
add_subdirectory(third_party/libmbfl)
@@ -32,11 +62,19 @@ add_subdirectory(third_party/timelib)
add_subdirectory(third_party/lz4)
add_subdirectory(third_party/double-conversion)
add_subdirectory(third_party/folly)
add_subdirectory(third_party/libzip)
if(ENABLE_FASTCGI)
add_subdirectory(third_party/ti)
add_subdirectory(third_party/thrift)
endif()
ADD_LIBRARY(hphp_runtime_static STATIC
${CXX_SOURCES} ${C_SOURCES} ${ASM_SOURCES})
SET_TARGET_PROPERTIES(hphp_runtime_static PROPERTIES OUTPUT_NAME "hphp_runtime")
SET_TARGET_PROPERTIES(hphp_runtime_static PROPERTIES PREFIX "lib")
SET_TARGET_PROPERTIES(hphp_runtime_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
hphp_link(hphp_runtime_static)
add_dependencies(hphp_runtime_static hphp_parser)
add_subdirectory("tools/bootstrap")
add_subdirectory(vixl)
add_subdirectory(neo)
@@ -44,13 +82,10 @@ add_subdirectory(parser)
add_subdirectory(zend)
add_subdirectory(util)
add_subdirectory(hhbbc)
add_subdirectory(compiler)
add_subdirectory(runtime)
add_subdirectory(runtime/ext_hhvm)
add_subdirectory(system)
add_subdirectory(hhvm)
add_subdirectory(system)
if (NOT "$ENV{HPHP_NOTEST}" STREQUAL "1")
add_subdirectory(test)
+2 -3
Ver Arquivo
@@ -1,9 +1,8 @@
Next release
- support date.timezone in ini files
- implement fileinfo
- special comparisons for DateTime
- <cool stuff goes here>
"Sausage" 14-Oct-2013
- Fixed issue that caused memory_get_usage to report double the actual usage.
- Direct invocation of callable arrays: $f = [$cls_or_instance, 'method']; $f()
- ASAN clean
- Support dynamically loadable extensions
+13 -8
Ver Arquivo
@@ -66,7 +66,7 @@
#include "hphp/compiler/analysis/live_dict.h"
#include "hphp/compiler/analysis/ref_dict.h"
#include "hphp/runtime/vm/runtime.h"
#include "hphp/runtime/base/builtin-functions.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/parser/location.h"
@@ -2108,6 +2108,7 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) {
}
cs->clearVisited();
cs->clearChildOfYield();
StatementPtr s = dpc(Statement, cs);
if (s) {
@@ -2360,6 +2361,9 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) {
case Expression::KindOfSimpleFunctionCall:
{
SimpleFunctionCallPtr sfc(spc(SimpleFunctionCall, e));
if (sfc->getName() == "hphp_create_continuation") {
m_inlineAsExpr = false;
}
sfc->updateVtFlags();
}
case Expression::KindOfDynamicFunctionCall:
@@ -2395,6 +2399,9 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) {
// expressions. TODO: revisit this later
m_inlineAsExpr = false;
break;
case Expression::KindOfYieldExpression:
spc(YieldExpression, e)->getValueExpression()->setChildOfYield();
break;
case Expression::KindOfUnaryOpExpression:
if (Option::EnableEval > Option::NoEval && spc(UnaryOpExpression, e)->
getOp() == T_EVAL) {
@@ -2530,10 +2537,8 @@ public:
}
private:
#define CONSTRUCT_EXP(from) \
#define CONSTRUCT_PARAMS(from) \
(from)->getScope(), (from)->getLocation()
#define CONSTRUCT_STMT(from) \
(from)->getScope(), (from)->getLabelScope(), (from)->getLocation()
AnalysisResultConstPtr m_ar;
bool m_changed;
@@ -2606,7 +2611,7 @@ private:
ExpressionListPtr el(
new ExpressionList(
CONSTRUCT_EXP(target),
CONSTRUCT_PARAMS(target),
ExpressionList::ListKindComma));
if (target->isUnused()) {
el->setUnused(true);
@@ -2950,7 +2955,7 @@ private:
slistPtr->insertElement(
ExpStatementPtr(
new ExpStatement(
CONSTRUCT_STMT(slistPtr), assertion)),
CONSTRUCT_PARAMS(slistPtr), assertion)),
idx);
}
break;
@@ -3031,12 +3036,12 @@ private:
} else {
ExpStatementPtr newExpStmt(
new ExpStatement(
CONSTRUCT_STMT(branch),
CONSTRUCT_PARAMS(branch),
after));
IfBranchStatementPtr newBranch(
new IfBranchStatement(
CONSTRUCT_STMT(branch),
CONSTRUCT_PARAMS(branch),
ExpressionPtr(), newExpStmt));
branches->addElement(newBranch);
+18 -22
Ver Arquivo
@@ -967,14 +967,11 @@ struct OptVisitor {
AnalysisResultPtr m_ar;
unsigned m_nscope;
JobQueueDispatcher<OptWorker<When>> *m_dispatcher;
JobQueueDispatcher<BlockScope *, OptWorker<When> > *m_dispatcher;
};
template <typename When>
class OptWorker : public JobQueueWorker<BlockScope*,
void*,
true,
true> {
class OptWorker : public JobQueueWorker<BlockScope *, true, true> {
public:
OptWorker() {}
@@ -993,8 +990,8 @@ public:
acc->second += 1;
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */
try {
auto visitor =
(DepthFirstVisitor<When, OptVisitor>*) m_context;
DepthFirstVisitor<When, OptVisitor > *visitor =
(DepthFirstVisitor<When, OptVisitor >*)m_opaque;
{
Lock ldep(BlockScope::s_depsMutex);
Lock lstate(BlockScope::s_jobStateMutex);
@@ -1183,7 +1180,7 @@ void OptWorker<Pre>::onThreadExit() {
} \
if (threadCount <= 0) threadCount = 1; \
this->m_data.m_dispatcher = \
new JobQueueDispatcher<worker>( \
new JobQueueDispatcher<BlockScope *, worker >( \
threadCount, true, 0, false, this); \
} while (0)
@@ -1228,7 +1225,7 @@ template <typename When>
void
AnalysisResult::preWaitCallback(bool first,
const BlockScopeRawPtrQueue &scopes,
void *context) {
void *opaque) {
// default is no-op
}
@@ -1237,7 +1234,7 @@ bool
AnalysisResult::postWaitCallback(bool first,
bool again,
const BlockScopeRawPtrQueue &scopes,
void *context) {
void *opaque) {
// default is no-op
return again;
}
@@ -1302,7 +1299,7 @@ struct BIPairCmp {
template <typename When>
void
AnalysisResult::processScopesParallel(const char *id,
void *context /* = NULL */) {
void *opaque /* = NULL */) {
BlockScopeRawPtrQueue scopes;
getScopesSet(scopes);
@@ -1339,7 +1336,7 @@ AnalysisResult::processScopesParallel(const char *id,
BlockScopeRawPtrQueue enqueued;
again = dfv.visitParallel(scopes, first, enqueued);
preWaitCallback<When>(first, scopes, context);
preWaitCallback<When>(first, scopes, opaque);
#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
{
@@ -1393,7 +1390,7 @@ AnalysisResult::processScopesParallel(const char *id,
std::cout << "Number of waiting scopes: " << numWaiting << std::endl;
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */
again = postWaitCallback<When>(first, again, scopes, context);
again = postWaitCallback<When>(first, again, scopes, opaque);
first = false;
} while (again);
dfv.data().stop();
@@ -1565,8 +1562,7 @@ DepthFirstVisitor<InferTypes, OptVisitor>::visitScope(BlockScopeRawPtr scope) {
template<>
bool AnalysisResult::postWaitCallback<InferTypes>(
bool first, bool again,
const BlockScopeRawPtrQueue &scopes, void *context) {
bool first, bool again, const BlockScopeRawPtrQueue &scopes, void *opaque) {
#ifdef HPHP_INSTRUMENT_TYPE_INF
std::cout << "Number of rescheduled: " <<
@@ -1672,12 +1668,12 @@ StatementPtr DepthFirstVisitor<Post, OptVisitor>::visit(StatementPtr stmt) {
return stmt->postOptimize(this->m_data.m_ar);
}
class FinalWorker : public JobQueueWorker<MethodStatementPtr, AnalysisResult*> {
class FinalWorker : public JobQueueWorker<MethodStatementPtr> {
public:
virtual void doJob(MethodStatementPtr m) {
try {
AliasManager am(1);
am.finalSetup(m_context->shared_from_this(), m);
am.finalSetup(((AnalysisResult*)m_opaque)->shared_from_this(), m);
} catch (Exception &e) {
Logger::Error("%s", e.getMessage().c_str());
}
@@ -1686,11 +1682,11 @@ public:
template<>
void AnalysisResult::preWaitCallback<Post>(
bool first, const BlockScopeRawPtrQueue &scopes, void *context) {
assert(!Option::ControlFlow || context != nullptr);
bool first, const BlockScopeRawPtrQueue &scopes, void *opaque) {
assert(!Option::ControlFlow || opaque != nullptr);
if (first && Option::ControlFlow) {
auto *dispatcher
= (JobQueueDispatcher<FinalWorker> *) context;
JobQueueDispatcher<FinalWorker::JobType, FinalWorker> *dispatcher
= (JobQueueDispatcher<FinalWorker::JobType, FinalWorker> *) opaque;
for (BlockScopeRawPtrQueue::const_iterator it = scopes.begin(),
end = scopes.end(); it != end; ++it) {
BlockScopeRawPtr scope = *it;
@@ -1714,7 +1710,7 @@ void AnalysisResult::postOptimize() {
}
if (threadCount <= 0) threadCount = 1;
JobQueueDispatcher<FinalWorker> dispatcher(
JobQueueDispatcher<FinalWorker::JobType, FinalWorker> dispatcher(
threadCount, true, 0, false, this);
processScopesParallel<Post>("PostOptimize", &dispatcher);
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+54 -305
Ver Arquivo
@@ -28,9 +28,6 @@
#include "hphp/runtime/vm/unit.h"
#include "hphp/util/hash.h"
#include <deque>
#include <utility>
namespace HPHP {
DECLARE_BOOST_TYPES(ClosureExpression);
@@ -98,7 +95,6 @@ public:
IterKind kind;
Id id;
};
#define O(name, imm, pop, push, flags) \
void name(imm);
#define NA
@@ -123,7 +119,6 @@ public:
#define AA ArrayData*
#define BA Label&
#define OA unsigned char
#define VSA std::vector<std::string>&
OPCODES
#undef O
#undef NA
@@ -144,7 +139,6 @@ public:
#undef AA
#undef BA
#undef OA
#undef VSA
private:
ConstructPtr m_node;
UnitEmitter& m_ue;
@@ -322,246 +316,13 @@ public:
class Funclet {
public:
explicit Funclet(Thunklet* body)
: m_body(body) {
}
Funclet(Thunklet* body, Label* entry) : m_body(body), m_entry(entry) {}
Thunklet* m_body;
Label m_entry;
};
class FinallyRouter;
DECLARE_BOOST_TYPES(FinallyRouterEntry);
/*
* FinallyRouterEntry represents a single level of the unified stack
* of constructs that are meaningful from the point of view of finally
* implementation. The levels are used to keep track of the information
* such as the actions that can be taken inside a block.
*/
class FinallyRouterEntry {
public:
enum EntryKind {
// Top-level (global) context.
GlobalEntry,
// Function body / method body entry.
FuncBodyEntry,
// Entry for finally fault funclets emitted after the body of
// a function
FuncFaultEntry,
// Try block entry (begins with try ends after catches).
TryFinallyEntry,
// Finally block entry (begins after catches ends after finally)
FinallyEntry,
// Loop OR a break statement.
LoopEntry,
};
typedef Emitter::IterPair IterPair;
typedef std::vector<IterPair> IterVec;
DECLARE_BOOST_TYPES(Action);
/*
* The structure represents a code path that potentially requires
* running finally blocks. A code path has an assigned state ID that
* is used inside switch statements emitted at the end of finally
* blocks. It also has an optional label (the destination to jump
* to after all the required finally blocks are run).
*/
struct Action {
static const int k_unsetState;
explicit Action(FinallyRouter* router);
~Action();
// Manage state ID reuse.
bool isAllocated();
void allocate();
void release();
FinallyRouter* m_router;
// The target to jump to once all the necessary finally blocks
// are run.
Label m_label;
// The state ID that identifies this action inside finally switch
// statements. This is the id assigned to the "state" unnamed
// local variable.
int m_state;
};
FinallyRouterEntry(FinallyRouter* router,
EntryKind kind,
FinallyRouterEntryPtr parent);
~FinallyRouterEntry();
// Helpers used for freeing iterators when appropriate actions
// require that.
void emitIterBreak(Emitter& e,
IterVec& iters,
Label& target);
void emitIterFree(Emitter& e, IterVec& iters);
void emitIterFree(Emitter& e);
// Emission of code snippets commencing actions. Method
// emitXYZ(e, ...) should be used instead of e.XYZ(...) in
// EmitterVisitor.
void emitReturn(Emitter& e, char sym);
void emitReturnImpl(Emitter& e,
char sym,
IterVec& iters);
void emitGoto(Emitter& e, StringData* name);
void emitGotoImpl(Emitter& e,
StringData* name,
IterVec& iters);
void emitBreak(Emitter& e, int depth);
void emitBreakImpl(Emitter& e,
int depth,
IterVec& iters);
void emitContinue(Emitter& e, int depth);
void emitContinueImpl(Emitter& e,
int depth,
IterVec& iters);
// Emit the switch statement in the finally epilogue. Optimizes
// cases where there is either just a fall-through case, or where
// there is a single case other than fall-through.
void emitFinallySwitch(Emitter& e);
// Helper for emitting beginning of single case from the finally
// epilogue.
void emitCase(Emitter& e, std::vector<Label*>& cases, ActionPtr action);
void emitReturnCase(Emitter& e, std::vector<Label*>& cases, char sym);
void emitReturnCaseImpl(Emitter& e, char sym, IterVec& iters);
void emitBreakCase(Emitter& e, std::vector<Label*>& cases, int depth);
void emitBreakCaseImpl(Emitter& e, int depth, IterVec& iters);
void emitContinueCase(Emitter& e, std::vector<Label*>& cases, int depth);
void emitContinueCaseImpl(Emitter& e, int depth, IterVec& iters);
// Helper for establishing the maximal depth of break / continue
// actions that are allocated.
int getBreakContinueDepth();
// Returns the maximal break / continue depth admissable (aka the
// number of nested loops).
int getMaxBreakContinueDepth();
// Methods used for emitting different cases for the finally
// epilogue switch.
void emitGotoCase(Emitter& e, std::vector<Label*>& cases, StringData* name);
void emitGotoCaseImpl(Emitter& e, StringData* name, IterVec& iters);
void emitReturnCases(Emitter& e, std::vector<Label*>& cases);
void emitGotoCases(Emitter& e, std::vector<Label*>& cases);
void emitBreakContinueCases(Emitter& e, std::vector<Label*>& cases);
void emitAllCases(Emitter& e, std::vector<Label*>& cases);
// Methods used for collecting labels corresponding to the cases
// from the finally epilogue. All the labels are accumulated
// inside the cases array. The array is eventually passed to
// e.Switch as the immediate argument.
void collectReturnCases(std::vector<Label*>& cases);
void collectGotoCases(std::vector<Label*>& cases);
void collectBreakContinueCases(std::vector<Label*>& cases);
void collectCase(std::vector<Label*>& cases,
ActionPtr action);
void collectAllCases(std::vector<Label*>& cases);
// The number of cases to be emitted. This is a helper used in
// establishing whether one of the optimized cases can be used.
int getCaseCount();
// Methods used for allocating new finally-aware code-paths.
// When alloc is set to false, the action is merely allocated in
// memory and shared among different entries. When alloc is set to
// true, the action is additionally assigned a state ID.
ActionPtr registerReturn(StatementPtr s, char sym);
ActionPtr registerGoto(StatementPtr s, StringData* name, bool alloc);
ActionPtr registerBreak(StatementPtr s, int depth, bool alloc);
ActionPtr registerContinue(StatementPtr s, int depth, bool alloc);
// Used to indicate that a particular label is present inside
// an entry. Labels don't have corresponding actions, however
// they need to be tracked in order to handle gotos appropriately.
void registerLabel(StatementPtr s, StringData* name);
// Yield / await is not supported inside a finally block for now.
// This method throws a parse time fatal whenever appropriate.
void registerYieldAwait(ExpressionPtr e);
FinallyRouter* m_router;
EntryKind m_kind;
// Only used for loop / break kind of entries.
Id m_iterId;
bool m_iterRef;
// Because of a bug in code emission, functions sometimes have
// inconsistent return flavours. Therefore instead of a single
// return action, there need to be one return action per flavor
// used. Once the bug is removed, this code can be simplified.
std::map<char, ActionPtr> m_returnActions;
// A map of goto actions. Each goto action is identified by the
// name of the destination label.
std::map<StringData*, ActionPtr, string_data_lt> m_gotoActions;
// A map of goto labels occurrning inside the statement represented
// by this entry. This value is used for establishing whether
// a finally block needs to be executed when performing gotos.
std::set<StringData*, string_data_lt> m_gotoLabels;
// Continue actions identified by their depth.
std::map<int, ActionPtr> m_continueActions;
// Break actions identified by their depth.
std::map<int, ActionPtr> m_breakActions;
// The label denoting the beginning of a finally block inside the
// current try. Only used when the entry kind is a try statement.
Label m_finallyLabel;
// The cases that need to be included in the switch statement. Only
// used when kind is set to try statement.
// These are the actions that are invoked inside the protected region
// protected by the try represented by this entry.
std::set<ActionPtr> m_finallyCases;
// The parent entry.
FinallyRouterEntryPtr m_parent;
};
class FinallyRouter {
public:
typedef FinallyRouterEntry::EntryKind EntryKind;
FinallyRouter();
~FinallyRouter();
// The top entry on the unified stack.
FinallyRouterEntryPtr top();
// Create an entry corresponding to the passed in statement s.
// If the statement is insignificant (e.g. is an if statement),
// nullptr is returned.
FinallyRouterEntryPtr createForStatement(StatementPtr s);
// Create a global (top-level) entry.
FinallyRouterEntryPtr createGlobal(StatementPtr s);
// Create an entry for a functiob body.
FinallyRouterEntryPtr createFuncBody(StatementPtr s);
// Create an entry for a fault funclet inside a function body
FinallyRouterEntryPtr createFuncFault(StatementPtr s);
// Helper function for creating entries.
FinallyRouterEntryPtr create(StatementPtr s, EntryKind kind);
// Enter/leave the passed in entry. Note that entries sometimes need be
// to be constructed before they are entered, or need to be accessed
// after they are left. This especially applies to constructs such
// as loops and try blocks.
void enter(FinallyRouterEntryPtr);
void leave(FinallyRouterEntryPtr);
// Functions used for handling state IDs allocation.
// FIXME (#3275259): This should be moved into global / func
// body / fault funclet entries in order to optimize state
// allocation. See the task description for more details.
int allocateState();
void releaseState(int state);
// The stack of all the entered entries.
std::vector<FinallyRouterEntryPtr> m_entries;
// The state IDs currently allocated. See FIXME above.
std::set<int> m_states;
Label* m_entry;
};
class EmitterVisitor {
friend class UnsetUnnamedLocalThunklet;
friend class FuncFinisher;
public:
explicit EmitterVisitor(UnitEmitter& ue);
~EmitterVisitor();
@@ -571,7 +332,6 @@ public:
void visitKids(ConstructPtr c);
void visit(FileScopePtr file);
void assignLocalVariableIds(FunctionScopePtr fs);
void assignFinallyVariableIds();
void fixReturnType(Emitter& e, FunctionCallPtr fn,
Func* builtinFunc = nullptr);
typedef std::vector<int> IndexChain;
@@ -589,7 +349,7 @@ public:
bool evalStackIsUnknown() { return m_evalStackIsUnknown; }
void popEvalStack(char symFlavor, int arg = -1, int pos = -1);
void popSymbolicLocal(Op opcode, int arg = -1, int pos = -1);
void popEvalStackMMany();
void popEvalStackLMany();
void popEvalStackMany(int len, char symFlavor);
void popEvalStackCVMany(int len);
void pushEvalStack(char symFlavor);
@@ -610,27 +370,16 @@ public:
|| isJumpTarget(m_ue.bcPos())
|| (instrFlags(getPrevOpcode()) & TF) == 0);
}
FinallyRouter& getFinallyRouter() { return m_finallyRouter; }
Id getStateLocal() {
DCHECK(m_stateLocal >= 0);
return m_stateLocal;
}
Id getRetLocal() {
DCHECK(m_retLocal >= 0);
return m_retLocal;
}
class IncludeTimeFatalException : public Exception {
public:
ConstructPtr m_node;
bool m_parseFatal;
IncludeTimeFatalException(ConstructPtr node, const char* fmt, ...)
: Exception(), m_node(node), m_parseFatal(false) {
: Exception(), m_node(node) {
va_list ap; va_start(ap, fmt); format(fmt, ap); va_end(ap);
}
virtual ~IncludeTimeFatalException() throw() {}
EXCEPTION_COMMON_IMPL(IncludeTimeFatalException);
void setParseFatal(bool b = true) { m_parseFatal = b; }
};
void pushIterScope(Id id, IterKind kind) {
@@ -688,6 +437,31 @@ private:
FuncEmitter* m_fe;
};
class ControlTargets {
public:
ControlTargets(Id itId, bool itRef, Label& brkTarg, Label& cntTarg)
: m_itId(itId), m_itRef(itRef), m_brkTarg(brkTarg), m_cntTarg(cntTarg)
{}
Id m_itId;
bool m_itRef;
Label& m_brkTarg; // Jump here for "break;" (after doing IterFree)
Label& m_cntTarg; // Jump here for "continue;"
};
class ControlTargetPusher {
public:
ControlTargetPusher(EmitterVisitor* e, Id itId, bool itRef, Label& brkTarg,
Label& cntTarg) : m_e(e) {
e->m_controlTargets.push_front(ControlTargets(itId, itRef, brkTarg,
cntTarg));
}
~ControlTargetPusher() {
m_e->m_controlTargets.pop_front();
}
private:
EmitterVisitor* m_e;
};
class ExnHandlerRegion {
public:
ExnHandlerRegion(Offset start, Offset end) : m_start(start),
@@ -706,22 +480,18 @@ private:
class FaultRegion {
public:
FaultRegion(Offset start,
Offset end,
Label* func,
Id iterId,
IterKind kind)
FaultRegion(Offset start, Offset end, Id iterId, IterKind kind)
: m_start(start)
, m_end(end)
, m_func(func)
, m_iterId(iterId)
, m_iterKind(kind) {}
, m_iterKind(kind)
{}
Offset m_start;
Offset m_end;
Label* m_func;
Id m_iterId;
IterKind m_iterKind;
Label m_func; // note: a pointer to this is handed out to the Funclet
};
class FPIRegion {
@@ -743,6 +513,9 @@ private:
int defI;
};
private:
void emitFatal(Emitter& e, const char* message);
private:
static const size_t kMinStringSwitchCases = 8;
UnitEmitter& m_ue;
@@ -769,19 +542,16 @@ private:
typedef tbb::concurrent_hash_map<const StringData*, int,
StringDataHashCompare> EmittedClosures;
static EmittedClosures s_emittedClosures;
std::deque<Funclet*> m_funclets;
std::map<StatementPtr, Funclet*> m_memoizedFunclets;
std::deque<ControlTargets> m_controlTargets;
std::deque<Funclet> m_funclets;
std::deque<ExnHandlerRegion*> m_exnHandlers;
std::deque<FaultRegion*> m_faultRegions;
std::deque<FPIRegion*> m_fpiRegions;
std::vector<Array> m_staticArrays;
std::set<std::string,stdltistr> m_hoistables;
LocationPtr m_tempLoc;
std::map<StringData*, Label, string_data_lt> m_gotoLabels;
std::vector<Label> m_yieldLabels;
FinallyRouter m_finallyRouter;
Id m_stateLocal;
Id m_retLocal;
MetaInfoBuilder m_metaInfo;
public:
bool checkIfStackEmpty(const char* forInstruction) const;
@@ -800,11 +570,16 @@ public:
void emitAGet(Emitter& e);
void emitCGetL2(Emitter& e);
void emitCGetL3(Emitter& e);
void emitPushL(Emitter& e);
void emitCGet(Emitter& e);
void emitVGet(Emitter& e);
void emitIsset(Emitter& e);
void emitIsType(Emitter& e, IsTypeOp op);
void emitIsNull(Emitter& e);
void emitIsArray(Emitter& e);
void emitIsObject(Emitter& e);
void emitIsString(Emitter& e);
void emitIsInt(Emitter& e);
void emitIsDouble(Emitter& e);
void emitIsBool(Emitter& e);
void emitEmpty(Emitter& e);
void emitUnset(Emitter& e, ExpressionPtr exp = ExpressionPtr());
void emitVisitAndUnset(Emitter& e, ExpressionPtr exp);
@@ -814,6 +589,7 @@ public:
void emitIncDec(Emitter& e, unsigned char cop);
void emitPop(Emitter& e);
void emitConvertToCell(Emitter& e);
void emitFreePendingIters(Emitter& e);
void emitConvertToCellIfVar(Emitter& e);
void emitConvertToCellOrLoc(Emitter& e);
void emitConvertSecondToCell(Emitter& e);
@@ -834,6 +610,7 @@ public:
void emitStringSwitch(Emitter& e, SwitchStatementPtr s,
std::vector<Label>& caseLabels, Label& done,
const SwitchState& state);
void emitIterBreak(Emitter& e, uint64_t n, Label& targ);
void markElem(Emitter& e);
void markNewElem(Emitter& e);
@@ -899,55 +676,28 @@ public:
bool emitCallUserFunc(Emitter& e, SimpleFunctionCallPtr node);
Func* canEmitBuiltinCall(const std::string& name, int numParams);
void emitFuncCall(Emitter& e, FunctionCallPtr node,
const char* nameOverride = nullptr,
ExpressionListPtr paramsOverride = nullptr);
void emitFuncCall(Emitter& e, FunctionCallPtr node);
void emitFuncCallArg(Emitter& e, ExpressionPtr exp, int paramId);
void emitBuiltinCallArg(Emitter& e, ExpressionPtr exp, int paramId,
bool byRef);
void emitBuiltinDefaultArg(Emitter& e, Variant& v, DataType t, int paramId);
void emitClass(Emitter& e, ClassScopePtr cNode, bool topLevel);
void emitTypedef(Emitter& e, TypedefStatementPtr);
void emitForeachListAssignment(Emitter& e,
ListAssignmentPtr la,
void emitForeachListAssignment(Emitter& e, ListAssignmentPtr la,
int vLocalId);
void emitForeach(Emitter& e,
ForEachStatementPtr fe,
FinallyRouterEntryPtr entry);
void emitForeach(Emitter& e, ForEachStatementPtr fe);
void emitRestoreErrorReporting(Emitter& e, Id oldLevelLoc);
void emitMakeUnitFatal(Emitter& e,
const char* msg,
FatalOp k = FatalOp::Runtime);
void emitMakeUnitFatal(Emitter& e, const std::string& message);
Funclet* addFunclet(Thunklet* body);
Funclet* addFunclet(StatementPtr stmt,
Thunklet* body);
Funclet* getFunclet(StatementPtr stmt);
void addFunclet(Thunklet* body, Label* entry);
void emitFunclets(Emitter& e);
struct FaultIterInfo {
Id iterId;
IterKind kind;
};
void newFaultRegion(Offset start,
Offset end,
Label* entry,
void newFaultRegion(Offset start, Offset end, Thunklet* t,
FaultIterInfo = FaultIterInfo { -1, KindOfIter });
void newFaultRegion(StatementPtr stmt,
Offset start,
Offset end,
Label* entry,
FaultIterInfo = FaultIterInfo { -1, KindOfIter });
void newFuncletAndRegion(Offset start,
Offset end,
Thunklet* t,
FaultIterInfo = FaultIterInfo { -1, KindOfIter });
void newFuncletAndRegion(StatementPtr stmt,
Offset start,
Offset end,
Thunklet* t,
FaultIterInfo = FaultIterInfo { -1, KindOfIter });
void newFPIRegion(Offset start, Offset end, Offset fpOff);
void copyOverExnHandlers(FuncEmitter* fe);
@@ -967,7 +717,6 @@ public:
void emitAllHHBC(AnalysisResultPtr ar);
extern "C" {
String hphp_compiler_serialize_code_model_for(String code, String prefix);
Unit* hphp_compiler_parse(const char* code, int codeLen, const MD5& md5,
const char* filename);
Unit* hphp_build_native_func_unit(const HhbcExtFuncInfo* builtinFuncs,
+67 -99
Ver Arquivo
@@ -13,11 +13,8 @@
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/file_scope.h"
#include <sys/stat.h>
#include "folly/ScopeGuard.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/class_scope.h"
@@ -26,6 +23,7 @@
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/function_scope.h"
#include <sys/stat.h>
#include "hphp/compiler/parser/parser.h"
#include "hphp/util/logger.h"
#include "hphp/util/util.h"
@@ -75,7 +73,8 @@ FunctionScopePtr FileScope::setTree(AnalysisResultConstPtr ar,
return createPseudoMain(ar);
}
void FileScope::cleanupForError(AnalysisResultConstPtr ar) {
void FileScope::cleanupForError(AnalysisResultConstPtr ar,
int line, const string &msg) {
for (StringToClassScopePtrVecMap::const_iterator iter = m_classes.begin();
iter != m_classes.end(); ++iter) {
BOOST_FOREACH(ClassScopePtr cls, iter->second) {
@@ -91,17 +90,8 @@ void FileScope::cleanupForError(AnalysisResultConstPtr ar) {
StringToClassScopePtrVecMap().swap(m_classes);
m_pseudoMain.reset();
m_tree.reset();
}
template <class Meth>
void makeFatalMeth(FileScope& file,
AnalysisResultConstPtr ar,
const std::string& msg,
int line,
Meth meth) {
LocationPtr loc(new Location());
LabelScopePtr labelScope(new LabelScope());
loc->file = file.getName().c_str();
loc->file = m_fileName.c_str();
loc->first(line, 0);
loc->last(line, 0);
BlockScopePtr scope;
@@ -110,30 +100,16 @@ void makeFatalMeth(FileScope& file,
SimpleFunctionCallPtr e(
new SimpleFunctionCall(scope, loc, "throw_fatal", false, args,
ExpressionPtr()));
meth(e);
ExpStatementPtr exp(new ExpStatement(scope, labelScope, loc, e));
StatementListPtr stmts(new StatementList(scope, labelScope, loc));
e->setThrowFatal();
ExpStatementPtr exp(new ExpStatement(scope, loc, e));
StatementListPtr stmts(new StatementList(scope, loc));
stmts->addElement(exp);
FunctionScopePtr fs = file.setTree(ar, stmts);
fs->setOuterScope(file.shared_from_this());
FunctionScopePtr fs = setTree(ar, stmts);
fs->setOuterScope(shared_from_this());
fs->getStmt()->resetScope(fs);
fs->getStmt()->setLocation(loc);
file.setOuterScope(const_cast<AnalysisResult*>(ar.get())->shared_from_this());
}
void FileScope::makeFatal(AnalysisResultConstPtr ar,
const std::string& msg,
int line) {
auto meth = [](SimpleFunctionCallPtr e) { e->setThrowFatal(); };
makeFatalMeth(*this, ar, msg, line, meth);
}
void FileScope::makeParseFatal(AnalysisResultConstPtr ar,
const std::string& msg,
int line) {
auto meth = [](SimpleFunctionCallPtr e) { e->setThrowParseFatal(); };
makeFatalMeth(*this, ar, msg, line, meth);
setOuterScope(const_cast<AnalysisResult*>(ar.get())->shared_from_this());
}
bool FileScope::addFunction(AnalysisResultConstPtr ar,
@@ -324,73 +300,66 @@ bool FileScope::insertClassUtil(AnalysisResultPtr ar,
void FileScope::analyzeIncludesHelper(AnalysisResultPtr ar) {
m_includeState = 1;
SCOPE_EXIT { m_includeState = 2; };
if (m_pseudoMain) {
StatementList &stmts = *getStmt();
bool hoistOnly = false;
for (int i = 0, n = stmts.getCount(); i < n; i++) {
StatementPtr s = stmts[i];
if (!s) continue;
if (s->is(Statement::KindOfClassStatement) ||
s->is(Statement::KindOfInterfaceStatement)) {
if (!m_pseudoMain) return;
StatementList &stmts = *getStmt();
bool hoistOnly = false;
for (int i = 0, n = stmts.getCount(); i < n; i++) {
StatementPtr s = stmts[i];
if (!s) continue;
if (s->is(Statement::KindOfClassStatement) ||
s->is(Statement::KindOfInterfaceStatement)) {
ClassScopeRawPtr cls(
static_pointer_cast<InterfaceStatement>(s)->getClassScope());
if (hoistOnly) {
const string &parent = cls->getOriginalParent();
if (cls->getBases().size() > (parent.empty() ? 0 : 1)) {
continue;
ClassScopeRawPtr cls(
static_pointer_cast<InterfaceStatement>(s)->getClassScope());
if (hoistOnly) {
const string &parent = cls->getOriginalParent();
if (cls->getBases().size() > (parent.empty() ? 0 : 1)) {
continue;
}
if (!parent.empty()) {
ClassScopeRawPtr c = ar->findClass(parent);
if (!c || (c->isVolatile() &&
!resolveClass(c) && !checkClass(parent))) {
continue;
}
}
}
if (!parent.empty()) {
ClassScopeRawPtr c = ar->findClass(parent);
if (!c || (c->isVolatile() &&
!resolveClass(c) && !checkClass(parent))) {
if (cls->isVolatile()) {
insertClassUtil(ar, cls, true);
}
continue;
}
if (s->is(Statement::KindOfFunctionStatement)) {
FunctionScopeRawPtr func(
static_pointer_cast<FunctionStatement>(s)->getFunctionScope());
if (func->isVolatile()) m_providedDefs.insert(func);
continue;
}
if (!hoistOnly && s->is(Statement::KindOfExpStatement)) {
ExpressionRawPtr exp(
static_pointer_cast<ExpStatement>(s)->getExpression());
if (exp && exp->is(Expression::KindOfIncludeExpression)) {
FileScopeRawPtr fs(
static_pointer_cast<IncludeExpression>(exp)->getIncludedFile(ar));
if (fs && fs->m_includeState != 1) {
if (!fs->m_includeState) {
if (m_module && fs->m_privateInclude) {
BOOST_FOREACH(BlockScopeRawPtr bs, m_providedDefs) {
fs->m_providedDefs.insert(bs);
}
}
fs->analyzeIncludesHelper(ar);
}
BOOST_FOREACH(BlockScopeRawPtr bs, fs->m_providedDefs) {
m_providedDefs.insert(bs);
}
continue;
}
}
}
if (cls->isVolatile()) {
insertClassUtil(ar, cls, true);
}
continue;
hoistOnly = true;
}
if (s->is(Statement::KindOfFunctionStatement)) {
FunctionScopeRawPtr func(
static_pointer_cast<FunctionStatement>(s)->getFunctionScope());
if (func->isVolatile()) m_providedDefs.insert(func);
continue;
}
if (!hoistOnly && s->is(Statement::KindOfExpStatement)) {
ExpressionRawPtr exp(
static_pointer_cast<ExpStatement>(s)->getExpression());
if (exp && exp->is(Expression::KindOfIncludeExpression)) {
FileScopeRawPtr fs(
static_pointer_cast<IncludeExpression>(exp)->getIncludedFile(ar));
if (fs && fs->m_includeState != 1) {
if (!fs->m_includeState) {
if (m_module && fs->m_privateInclude) {
BOOST_FOREACH(BlockScopeRawPtr bs, m_providedDefs) {
fs->m_providedDefs.insert(bs);
}
}
fs->analyzeIncludesHelper(ar);
}
BOOST_FOREACH(BlockScopeRawPtr bs, fs->m_providedDefs) {
m_providedDefs.insert(bs);
}
continue;
}
}
}
hoistOnly = true;
}
m_includeState = 2;
}
@@ -400,9 +369,11 @@ void FileScope::analyzeIncludes(AnalysisResultPtr ar) {
}
}
void FileScope::visit(AnalysisResultPtr ar,
void (*cb)(AnalysisResultPtr, StatementPtr, void*),
void *data) {
void *data)
{
if (m_pseudoMain) {
cb(ar, m_pseudoMain->getStmt(), data);
}
@@ -417,11 +388,8 @@ const string &FileScope::pseudoMainName() {
FunctionScopePtr FileScope::createPseudoMain(AnalysisResultConstPtr ar) {
StatementListPtr st = m_tree;
LabelScopePtr labelScope(new LabelScope());
FunctionStatementPtr f
(new FunctionStatement(BlockScopePtr(),
labelScope,
LocationPtr(),
(new FunctionStatement(BlockScopePtr(), LocationPtr(),
ModifierExpressionPtr(),
false, pseudoMainName(),
ExpressionListPtr(), TypeAnnotationPtr(),
+2 -6
Ver Arquivo
@@ -62,7 +62,6 @@ public:
IsFoldable = 0x1000,// function can be constant folded
NeedsActRec = 0x2000,// builtin function needs ActRec
AllowOverride = 0x4000,// allow override of systemlib or builtin
NeedsFinallyLocals = 0x8000,
};
typedef boost::adjacency_list<boost::setS, boost::vecS> Graph;
@@ -108,11 +107,8 @@ public:
* are the only functions a parser calls upon analysis results.
*/
FunctionScopePtr setTree(AnalysisResultConstPtr ar, StatementListPtr tree);
void cleanupForError(AnalysisResultConstPtr ar);
void makeFatal(AnalysisResultConstPtr ar,
const std::string& msg, int line);
void makeParseFatal(AnalysisResultConstPtr ar,
const std::string& msg, int line);
void cleanupForError(AnalysisResultConstPtr ar,
int line, const std::string &msg);
bool addFunction(AnalysisResultConstPtr ar, FunctionScopePtr funcScope);
bool addClass(AnalysisResultConstPtr ar, ClassScopePtr classScope);
-5
Ver Arquivo
@@ -354,11 +354,6 @@ bool FunctionScope::needsActRec() const {
return res;
}
bool FunctionScope::needsFinallyLocals() const {
bool res = (m_attribute & FileScope::NeedsFinallyLocals);
return res;
}
bool FunctionScope::mayContainThis() {
return inPseudoMain() || getContainingClass() ||
(isClosure() && !m_modifiers->isStatic());
-2
Ver Arquivo
@@ -226,8 +226,6 @@ public:
bool allowOverride() const;
void setAllowOverride();
bool needsFinallyLocals() const;
/**
* Whether this function is a runtime helper function
*/
+1 -2
Ver Arquivo
@@ -623,8 +623,7 @@ public:
e->setLocation(sub->getLocation());
e->setBlockScope(sub->getScope());
ExpStatementPtr exp(
new ExpStatement(sub->getScope(), sub->getLabelScope(),
sub->getLocation(), e));
new ExpStatement(sub->getScope(), sub->getLocation(), e));
sl->insertElement(exp, ix);
}
}
-1
Ver Arquivo
@@ -21,7 +21,6 @@
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/runtime/base/builtin-functions.h"
#include "hphp/runtime/vm/runtime.h"
#include <boost/format.hpp>
using namespace HPHP;
+2 -148
Ver Arquivo
@@ -14,16 +14,15 @@
+----------------------------------------------------------------------+
*/
#include <stdarg.h>
#include "hphp/compiler/code_generator.h"
#include "hphp/compiler/code_model_enums.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/runtime/base/zend-printf.h"
#include "hphp/util/util.h"
#include "hphp/util/hash.h"
#include <boost/format.hpp>
@@ -425,148 +424,3 @@ int CodeGenerator::ClassScopeCompare::cmp(const ClassScopeRawPtr &p1,
if (d) return d;
return strcasecmp(p1->getName().c_str(), p2->getName().c_str());
}
void CodeGenerator::printObjectHeader(const std::string className,
int numProperties) {
std::string prefixedClassName;
prefixedClassName.append(m_astPrefix);
prefixedClassName.append(className);
m_astClassNames.push_back(prefixedClassName);
printf("O:%d:\"%s\":%d:{",
(int)prefixedClassName.length(), prefixedClassName.c_str(), numProperties);
}
void CodeGenerator::printObjectFooter() {
printf("}");
m_astClassNames.pop_back();
}
void CodeGenerator::printPropertyHeader(const std::string propertyName) {
auto prefixedClassName = m_astClassNames.back();
auto len = 2+prefixedClassName.length()+propertyName.length();
printf("s:%d:\"", (int)len);
*m_out << (char)0;
printf("%s", prefixedClassName.c_str());
*m_out << (char)0;
printf("%s\";", propertyName.c_str());
}
void CodeGenerator::printValue(double v) {
*m_out << "d:";
if (std::isnan(v)) {
*m_out << "NAN";
} else if (std::isinf(v)) {
if (v < 0) *m_out << '-';
*m_out << "INF";
} else {
char *buf;
if (v == 0.0) v = 0.0; // so to avoid "-0" output
vspprintf(&buf, 0, "%.*H", 14, v);
m_out->write(buf, strlen(buf));
free(buf);
}
*m_out << ';';
}
void CodeGenerator::printValue(int32_t value) {
printf("i:%d;", value);
}
void CodeGenerator::printValue(int64_t value) {
printf("i:%ld;", value);
}
void CodeGenerator::printValue(std::string value) {
printf("s:%d:\"", (int)value.length());
getStream()->write(value.c_str(), value.length());
printf("\";");
}
void CodeGenerator::printModifierVector(std::string value) {
printf("V:6:\"Vector\":1:{");
printObjectHeader("Modifier", 1);
printPropertyHeader("name");
printValue(value);
printObjectFooter();
printf("}");
}
void CodeGenerator::printTypeExpression(std::string value) {
printObjectHeader("TypeExpression", 1);
printPropertyHeader("name");
printValue(value);
printObjectFooter();
}
void CodeGenerator::printExpression(ExpressionPtr expression, bool isRef) {
if (isRef) {
printObjectHeader("UnaryOpExpression", 4);
printPropertyHeader("expression");
expression->outputCodeModel(*this);
printPropertyHeader("operation");
printValue(PHP_REFERENCE_OP);
printPropertyHeader("location");
printLocation(expression->getLocation());
printObjectFooter();
} else {
expression->outputCodeModel(*this);
}
}
void CodeGenerator::printExpressionVector(ExpressionListPtr el) {
printf("V:6:\"Vector\":%d:{", el->getCount());
if (el->getCount() > 0) {
el->outputCodeModel(*this);
}
printf("}");
}
void CodeGenerator::printExpressionVector(ExpressionPtr e) {
printf("V:6:\"Vector\":1:{");
e->outputCodeModel(*this);
printf("}");
}
void CodeGenerator::printAsBlock(StatementPtr s) {
if (s->is(Statement::KindOfBlockStatement)) {
s->outputCodeModel(*this);
} else {
printObjectHeader("BlockStatement", 2);
printPropertyHeader("statements");
if (s->is(Statement::KindOfStatementList)) {
auto sl = static_pointer_cast<StatementList>(s);
printStatementVector(sl);
} else {
printf("V:6:\"Vector\":1:{");
s->outputCodeModel(*this);
printf("}");
}
printPropertyHeader("location");
printLocation(s->getLocation());
printObjectFooter();
}
}
void CodeGenerator::printStatementVector(StatementListPtr sl) {
printf("V:6:\"Vector\":%d:{", sl->getCount());
if (sl->getCount() > 0) {
sl->outputCodeModel(*this);
}
printf("}");
}
void CodeGenerator::printLocation(LocationPtr location) {
if (location == nullptr) return;
printObjectHeader("SourceLocation", 4);
printPropertyHeader("startLine");
printValue(location->line0);
printPropertyHeader("endLine");
printValue(location->line1);
printPropertyHeader("startColumn");
printValue(location->char0);
printPropertyHeader("endColumn");
printValue(location->char1);
printObjectFooter();
}
-27
Ver Arquivo
@@ -24,16 +24,12 @@ namespace HPHP {
DECLARE_BOOST_TYPES(AnalysisResult);
DECLARE_BOOST_TYPES(Statement);
DECLARE_BOOST_TYPES(StatementList);
DECLARE_BOOST_TYPES(Construct);
DECLARE_BOOST_TYPES(BlockScope);
DECLARE_BOOST_TYPES(ClassScope);
DECLARE_BOOST_TYPES(FunctionScope);
DECLARE_BOOST_TYPES(FileScope);
DECLARE_BOOST_TYPES(LoopStatement);
DECLARE_BOOST_TYPES(Location);
DECLARE_BOOST_TYPES(Expression);
DECLARE_BOOST_TYPES(ExpressionList);
class CodeGenerator {
public:
@@ -49,7 +45,6 @@ public:
SystemCPP, // special mode for generating builtin classes
TextHHBC, // HHBC dump in human-readable format
BinaryHHBC, // serialized HHBC
CodeModel, // serialized Code Model classes
};
enum Stream {
@@ -270,34 +265,12 @@ public:
FileScopeRawPtr getLiteralScope() const {
return m_literalScope;
}
/**
* Support for printing AST nodes in PHP serialize() format.
*/
void printObjectHeader(const std::string className, int numProperties);
void printPropertyHeader(const std::string propertyName);
void printObjectFooter();
void printValue(double value);
void printValue(int32_t value);
void printValue(int64_t value);
void printValue(std::string value);
void printModifierVector(std::string value);
void printTypeExpression(std::string value);
void printExpression(ExpressionPtr expression, bool isRef);
void printExpressionVector(ExpressionListPtr el);
void printExpressionVector(ExpressionPtr e);
void printAsBlock(StatementPtr s);
void printStatementVector(StatementListPtr sl);
void printLocation(LocationPtr location);
void setAstClassPrefix(const std::string &prefix) { m_astPrefix = prefix; }
private:
std::string m_filename;
Stream m_curStream;
std::ostream *m_streams[StreamCount];
std::ostream *m_out;
Output m_output;
std::string m_astPrefix;
std::vector<std::string> m_astClassNames;
bool m_verbose;
int m_indentation[StreamCount];
-103
Ver Arquivo
@@ -1,103 +0,0 @@
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
// This file is @generated by tools/code-model/GenerateEnums.sh
#ifndef incl_HPHP_CODE_MODEL_ENUMS_H_
#define incl_HPHP_CODE_MODEL_ENUMS_H_
namespace HPHP {
/** The kinds of operations that IBinaryOpExpressions can perform. */
enum CodeModelBinaryOperator {
PHP_AND_ASSIGN = 1,
PHP_AND = 2,
PHP_ARRAY_ELEMENT = 3,
PHP_ARRAY_PAIR = 4,
PHP_ASSIGNMENT = 5,
PHP_BOOLEAN_AND = 6,
PHP_BOOLEAN_OR = 7,
PHP_CAST = 8,
PHP_CONCAT_ASSIGN = 9,
PHP_CONCAT = 10,
PHP_DIVIDE_ASSIGN = 11,
PHP_DIVIDE = 12,
PHP_INSTANCEOF = 13,
PHP_IS_EQUAL = 14,
PHP_IS_GREATER = 15,
PHP_IS_GREATER_OR_EQUAL = 16,
PHP_IS_IDENTICAL = 17,
PHP_IS_NOT_IDENTICAL = 18,
PHP_IS_NOT_EQUAL = 19,
PHP_IS_SMALLER = 20,
PHP_IS_SMALLER_OR_EQUAL = 21,
PHP_LOGICAL_AND = 22,
PHP_LOGICAL_OR = 23,
PHP_LOGICAL_XOR = 24,
PHP_MINUS_ASSIGN = 25,
PHP_MINUS = 26,
PHP_MODULUS_ASSIGN = 27,
PHP_MODULUS = 28,
PHP_MULTIPLY_ASSIGN = 29,
PHP_MULTIPLY = 30,
PHP_OR_ASSIGN = 31,
PHP_OR = 32,
PHP_PLUS_ASSIGN = 33,
PHP_PLUS = 34,
PHP_SHIFT_LEFT_ASSIGN = 35,
PHP_SHIFT_LEFT = 36,
PHP_SHIFT_RIGHT_ASSIGN = 37,
PHP_SHIFT_RIGHT = 38,
PHP_XOR_ASSIGN = 39,
PHP_XOR = 40,
};
/** The kinds of operations that IUnaryOpExpressions can perform. */
enum CodeModelUnaryOperator {
PHP_ARRAY_CAST_OP = 1,
PHP_ARRAY_APPEND_POINT_OP = 2,
PHP_AWAIT_OP = 3,
PHP_BOOL_CAST_OP = 4,
PHP_BITWISE_NOT_OP = 5,
PHP_CLONE_OP = 6,
PHP_DYNAMIC_VARIABLE_OP = 7,
PHP_ERROR_CONTROL_OP = 8,
PHP_FLOAT_CAST_OP = 9,
PHP_INCLUDE_OP = 10,
PHP_INCLUDE_ONCE_OP = 11,
PHP_INT_CAST_OP = 12,
PHP_MINUS_OP = 13,
PHP_NOT_OP = 14,
PHP_OBJECT_CAST_OP = 15,
PHP_PLUS_OP = 16,
PHP_POST_DECREMENT_OP = 17,
PHP_POST_INCREMENT_OP = 18,
PHP_PRE_DECREMENT_OP = 19,
PHP_PRE_INCREMENT_OP = 20,
PHP_REFERENCE_OP = 21,
PHP_REQUIRE_OP = 22,
PHP_REQUIRE_ONCE_OP = 23,
PHP_STRING_CAST_OP = 24,
PHP_UNSET_CAST_OP = 25,
};
/** Enumerates the kinds of type declaration statements. */
enum CodeModelTypeKind {
PHP_CLASS = 1,
PHP_INTERFACE = 2,
PHP_TRAIT = 3,
};
}
#endif // incl_HPHP_CODE_MODEL_ENUMS_H_
+3 -4
Ver Arquivo
@@ -344,8 +344,8 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
return 1;
}
if (vm.count("version")) {
#ifdef HHVM_VERSION
#undef HHVM_VERSION
#ifdef HPHP_VERSION
#undef HPHP_VERSION
#endif
#ifdef HPHP_COMPILER_STR
@@ -358,7 +358,7 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
#define HPHP_COMPILER_STR "HipHop Compiler v"
#endif
#define HHVM_VERSION(v) cout << HPHP_COMPILER_STR #v << "\n";
#define HPHP_VERSION(v) cout << HPHP_COMPILER_STR #v << "\n";
#include "../version" // nolint
cout << "Compiler: " << kCompilerId << "\n";
@@ -596,7 +596,6 @@ int process(const CompilerOptions &po) {
return 1;
}
if (Option::WholeProgram || po.target == "analyze") {
Timer timer(Timer::WallTime, "analyzeProgram");
ar->analyzeProgram();
}
}
+6 -7
Ver Arquivo
@@ -166,6 +166,10 @@ public:
void clearKilled() { m_flags.killed = false; }
bool isKilled() const { return m_flags.killed; }
void setChildOfYield() { m_flags.childOfYield = true; }
void clearChildOfYield() { m_flags.childOfYield = false; }
bool isChildOfYield() const { return m_flags.childOfYield; }
BlockScopeRawPtr getScope() const { return m_blockScope; }
void setBlockScope(BlockScopeRawPtr scope) { m_blockScope = scope; }
FileScopeRawPtr getFileScope() const {
@@ -195,8 +199,7 @@ public:
}
template<typename T>
std::shared_ptr<T> Clone(std::shared_ptr<T> constr,
BlockScopePtr scope) {
std::shared_ptr<T> Clone(std::shared_ptr<T> constr, BlockScopePtr scope) {
if (constr) {
constr = constr->clone();
constr->resetScope(scope);
@@ -244,11 +247,6 @@ public:
const AstWalkerStateVec &start,
ConstructPtr endBefore, ConstructPtr endAfter);
/**
* Generates a serialized Code Model corresponding to this AST.
*/
virtual void outputCodeModel(CodeGenerator &cg) = 0;
/**
* Called when generating code.
*/
@@ -301,6 +299,7 @@ private:
unsigned killed : 1;
unsigned refCounted : 2; // high bit indicates whether its valid
unsigned inited : 2; // high bit indicates whether its valid
unsigned childOfYield : 1; // parent node is yield
} m_flags;
};
protected:
@@ -19,7 +19,6 @@
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/code_model_enums.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/expression/static_member_expression.h"
#include "hphp/compiler/analysis/function_scope.h"
@@ -389,42 +388,6 @@ ExpressionPtr ArrayElementExpression::unneeded() {
return Expression::unneeded();
}
///////////////////////////////////////////////////////////////////////////////
void ArrayElementExpression::outputCodeModel(CodeGenerator &cg) {
if (Option::ConvertSuperGlobals && m_global && !m_dynamicGlobal &&
getScope() && (getScope()->is(BlockScope::ProgramScope) ||
getScope()-> getVariables()->
isConvertibleSuperGlobal(m_globalName))) {
cg.printObjectHeader("SimpleVariableExpression", 2);
cg.printPropertyHeader("name");
cg.printValue(m_globalName);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
} else if (m_offset) {
cg.printObjectHeader("BinaryOpExpression", 4);
cg.printPropertyHeader("expression1");
m_variable->outputCodeModel(cg);
cg.printPropertyHeader("expression2");
cg.printExpression(m_offset, false);
cg.printPropertyHeader("operation");
cg.printValue(PHP_ARRAY_ELEMENT);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
} else {
cg.printObjectHeader("UnaryOpExpression", 4);
cg.printPropertyHeader("expression");
m_variable->outputCodeModel(cg);
cg.printPropertyHeader("operation");
cg.printValue(PHP_ARRAY_APPEND_POINT_OP);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -17,7 +17,6 @@
#include "hphp/compiler/expression/array_pair_expression.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/compiler/code_model_enums.h"
#include "hphp/parser/hphp.tab.hpp"
using namespace HPHP;
@@ -123,25 +122,6 @@ bool ArrayPairExpression::canonCompare(ExpressionPtr e) const {
return m_ref == a->m_ref;
}
///////////////////////////////////////////////////////////////////////////////
void ArrayPairExpression::outputCodeModel(CodeGenerator &cg) {
if (m_name) {
cg.printObjectHeader("BinaryOpExpression", 4);
cg.printPropertyHeader("expression1");
m_name->outputCodeModel(cg);
cg.printPropertyHeader("expression2");
cg.printExpression(m_value, m_ref);
cg.printPropertyHeader("operation");
cg.printValue(PHP_ARRAY_PAIR);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
} else {
cg.printExpression(m_value, m_ref);
}
return;
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -26,7 +26,6 @@
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/compiler/code_model_enums.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
@@ -307,21 +306,6 @@ TypePtr AssignmentExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
return inferAssignmentTypes(ar, type, coerce, m_variable, m_value);
}
///////////////////////////////////////////////////////////////////////////////
void AssignmentExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("BinaryOpExpression", 4);
cg.printPropertyHeader("expression1");
m_variable->outputCodeModel(cg);
cg.printPropertyHeader("expression2");
cg.printExpression(m_value, m_ref);
cg.printPropertyHeader("operation");
cg.printValue(PHP_ASSIGNMENT);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -16,7 +16,6 @@
#include "hphp/compiler/expression/await_expression.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/code_model_enums.h"
using namespace HPHP;
@@ -83,18 +82,6 @@ TypePtr AwaitExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
return Type::Variant;
}
///////////////////////////////////////////////////////////////////////////////
void AwaitExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("UnaryOpExpression", 2);
cg.printPropertyHeader("expression");
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("operation");
cg.printValue(PHP_AWAIT_OP);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -21,7 +21,6 @@
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/compiler/code_model_enums.h"
#include "hphp/runtime/base/complex-types.h"
#include "hphp/runtime/base/type-conversions.h"
#include "hphp/runtime/base/builtin-functions.h"
@@ -33,7 +32,6 @@
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/statement/loop_statement.h"
#include "hphp/runtime/base/tv-arith.h"
#include "hphp/runtime/vm/runtime.h"
using namespace HPHP;
@@ -913,76 +911,6 @@ TypePtr BinaryOpExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
return rt;
}
///////////////////////////////////////////////////////////////////////////////
void BinaryOpExpression::outputCodeModel(CodeGenerator &cg) {
if (m_op == T_COLLECTION) {
cg.printObjectHeader("CollectionInitializerExpression", 3);
cg.printPropertyHeader("collection");
m_exp1->outputCodeModel(cg);
cg.printPropertyHeader("arguments");
cg.printExpressionVector(static_pointer_cast<ExpressionList>(m_exp2));
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
return;
}
cg.printObjectHeader("BinaryOpExpression", 4);
cg.printPropertyHeader("expression1");
m_exp1->outputCodeModel(cg);
cg.printPropertyHeader("expression2");
m_exp2->outputCodeModel(cg);
cg.printPropertyHeader("operation");
int op = 0;
switch (m_op) {
case T_PLUS_EQUAL: op = PHP_PLUS_ASSIGN; break;
case T_MINUS_EQUAL: op = PHP_MINUS_ASSIGN; break;
case T_MUL_EQUAL: op = PHP_MULTIPLY_ASSIGN; break;
case T_DIV_EQUAL: op = PHP_DIVIDE_ASSIGN; break;
case T_CONCAT_EQUAL: op = PHP_CONCAT_ASSIGN; break;
case T_MOD_EQUAL: op = PHP_MODULUS_ASSIGN; break;
case T_AND_EQUAL: op = PHP_AND_ASSIGN; break;
case T_OR_EQUAL: op = PHP_OR_ASSIGN; break;
case T_XOR_EQUAL: op = PHP_XOR_ASSIGN; break;
case T_SL_EQUAL: op = PHP_SHIFT_LEFT_ASSIGN; break;
case T_SR_EQUAL: op = PHP_SHIFT_RIGHT_ASSIGN; break;
case T_BOOLEAN_OR: op = PHP_BOOLEAN_OR; break;
case T_BOOLEAN_AND: op = PHP_BOOLEAN_AND; break;
case T_LOGICAL_OR: op = PHP_LOGICAL_OR; break;
case T_LOGICAL_AND: op = PHP_LOGICAL_AND; break;
case T_LOGICAL_XOR: op = PHP_LOGICAL_XOR; break;
case '|': op = PHP_OR; break;
case '&': op = PHP_AND; break;
case '^': op = PHP_XOR; break;
case '.': op = PHP_CONCAT; break;
case '+': op = PHP_PLUS; break;
case '-': op = PHP_MINUS; break;
case '*': op = PHP_MULTIPLY; break;
case '/': op = PHP_DIVIDE; break;
case '%': op = PHP_MODULUS; break;
case T_SL: op = PHP_SHIFT_LEFT; break;
case T_SR: op = PHP_SHIFT_RIGHT; break;
case T_IS_IDENTICAL: op = PHP_IS_IDENTICAL; break;
case T_IS_NOT_IDENTICAL: op = PHP_IS_NOT_IDENTICAL; break;
case T_IS_EQUAL: op = PHP_IS_EQUAL; break;
case T_IS_NOT_EQUAL: op = PHP_IS_NOT_EQUAL; break;
case '<': op = PHP_IS_SMALLER; break;
case T_IS_SMALLER_OR_EQUAL: op = PHP_IS_SMALLER_OR_EQUAL; break;
case '>': op = PHP_IS_GREATER; break;
case T_IS_GREATER_OR_EQUAL: op = PHP_IS_GREATER_OR_EQUAL; break;
case T_INSTANCEOF: op = PHP_INSTANCEOF; break;
default:
assert(false);
}
cg.printValue(op);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -221,18 +221,6 @@ bool ClassConstantExpression::canonCompare(ExpressionPtr e) const {
m_className == static_cast<ClassConstantExpression*>(e.get())->m_className;
}
///////////////////////////////////////////////////////////////////////////////
void ClassConstantExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ClassPropertyExpression", 2);
cg.printPropertyHeader("className");
StaticClassName::outputCodeModel(cg);
cg.printPropertyHeader("propertyName");
cg.printValue(m_varName);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -279,19 +279,6 @@ bool ClosureExpression::hasStaticLocalsImpl(ConstructPtr root) {
return false;
}
///////////////////////////////////////////////////////////////////////////////
void ClosureExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ClosureExpression", 3);
cg.printPropertyHeader("function");
m_func->outputCodeModel(cg);
cg.printPropertyHeader("capturedVariables");
cg.printExpressionVector(m_vars);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -273,17 +273,6 @@ TypePtr ConstantExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
return actualType;
}
///////////////////////////////////////////////////////////////////////////////
void ConstantExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("SimpleVariableExpression", 2);
cg.printPropertyHeader("name");
cg.printValue(getNonNSOriginalName());
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -113,26 +113,6 @@ TypePtr DynamicFunctionCall::inferTypes(AnalysisResultPtr ar, TypePtr type,
return Type::Variant;
}
///////////////////////////////////////////////////////////////////////////////
void DynamicFunctionCall::outputCodeModel(CodeGenerator &cg) {
if (m_class || !m_className.empty()) {
cg.printObjectHeader("ClassMethodCallExpression", 4);
cg.printPropertyHeader("className");
StaticClassName::outputCodeModel(cg);
cg.printPropertyHeader("methodExpression");
} else {
cg.printObjectHeader("SimpleFunctionCallExpression", 3);
cg.printPropertyHeader("functionExpression");
}
m_nameExp->outputCodeModel(cg);
cg.printPropertyHeader("arguments");
cg.printExpressionVector(m_params);
cg.printPropertyHeader("location");
cg.printLocation(m_nameExp->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
void DynamicFunctionCall::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) {
@@ -19,7 +19,6 @@
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/code_model_enums.h"
using namespace HPHP;
@@ -88,19 +87,6 @@ TypePtr DynamicVariable::inferTypes(AnalysisResultPtr ar, TypePtr type,
return m_implementedType = Type::Variant;
}
///////////////////////////////////////////////////////////////////////////////
void DynamicVariable::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("UnaryOpExpression", 3);
cg.printPropertyHeader("expression");
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("operation");
cg.printValue(PHP_DYNAMIC_VARIABLE_OP) ;
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -119,21 +119,6 @@ bool EncapsListExpression::canonCompare(ExpressionPtr e) const {
return m_type == el->m_type;
}
///////////////////////////////////////////////////////////////////////////////
void EncapsListExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("EncapsListExpression", 2);
cg.printPropertyHeader("delimiter");
cg.printValue(m_type);
if (m_exps) {
cg.printPropertyHeader("expressions");
cg.printExpressionVector(m_exps);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
+1
Ver Arquivo
@@ -71,6 +71,7 @@ ExpressionPtr Expression::replaceValue(ExpressionPtr rep) {
rep->clearContext(AssignmentRHS);
rep = el;
}
if (isChildOfYield()) rep->setChildOfYield();
if (rep->is(KindOfSimpleVariable) && !is(KindOfSimpleVariable)) {
static_pointer_cast<SimpleVariable>(rep)->setAlwaysStash();
}
-5
Ver Arquivo
@@ -36,7 +36,6 @@
virtual ExpressionPtr clone(); \
virtual TypePtr inferTypes(AnalysisResultPtr ar, TypePtr type, \
bool coerce); \
virtual void outputCodeModel(CodeGenerator &cg); \
virtual void outputPHP(CodeGenerator &cg, AnalysisResultPtr ar);
#define DECLARE_EXPRESSION_VIRTUAL_FUNCTIONS \
DECLARE_BASE_EXPRESSION_VIRTUAL_FUNCTIONS; \
@@ -350,10 +349,6 @@ public:
return isNoRemove() && m_assertedType;
}
virtual bool allowCellByRef() const {
return false;
}
static ExpressionPtr MakeConstant(AnalysisResultConstPtr ar,
BlockScopePtr scope,
LocationPtr loc,
+14 -9
Ver Arquivo
@@ -33,6 +33,7 @@ using namespace HPHP;
ExpressionList::ExpressionList(EXPRESSION_CONSTRUCTOR_PARAMETERS,
ListKind kind)
: Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(ExpressionList)),
m_outputCount(-1),
m_arrayElements(false), m_collectionType(0), m_kind(kind) {
}
@@ -248,6 +249,19 @@ void ExpressionList::stripConcat() {
}
}
void ExpressionList::setOutputCount(int count) {
assert(count >= 0 && count <= (int)m_exps.size());
m_outputCount = count;
}
int ExpressionList::getOutputCount() const {
return m_outputCount < 0 ? m_exps.size() : m_outputCount;
}
void ExpressionList::resetOutputCount() {
m_outputCount = -1;
}
void ExpressionList::markParam(int p, bool noRefWrapper) {
ExpressionPtr param = (*this)[p];
if (param->hasContext(Expression::InvokeArgument)) {
@@ -464,15 +478,6 @@ bool ExpressionList::canonCompare(ExpressionPtr e) const {
m_kind == l->m_kind;
}
///////////////////////////////////////////////////////////////////////////////
void ExpressionList::outputCodeModel(CodeGenerator &cg) {
for (unsigned int i = 0; i < m_exps.size(); i++) {
ExpressionPtr exp = m_exps[i];
cg.printExpression(exp, exp?exp->hasContext(RefParameter):false);
}
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
+9
Ver Arquivo
@@ -75,6 +75,14 @@ public:
void setCollectionType(int cType);
/**
* When a function call has too many arguments, we only want to output
* max number of arguments, by limiting output count of subexpressions.
*/
void setOutputCount(int count);
int getOutputCount() const;
void resetOutputCount();
virtual bool canonCompare(ExpressionPtr e) const;
/**
@@ -89,6 +97,7 @@ private:
unsigned int checkLitstrKeys() const;
ExpressionPtrVec m_exps;
int m_outputCount;
bool m_arrayElements;
int m_collectionType;
ListKind m_kind;
@@ -283,12 +283,6 @@ TypePtr IncludeExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
return UnaryOpExpression::inferTypes(ar, type, coerce);
}
///////////////////////////////////////////////////////////////////////////////
void IncludeExpression::outputCodeModel(CodeGenerator &cg) {
UnaryOpExpression::outputCodeModel(cg);
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-13
Ver Arquivo
@@ -273,19 +273,6 @@ TypePtr ListAssignment::inferTypes(AnalysisResultPtr ar, TypePtr type,
return m_array->inferAndCheck(ar, Type::Variant, false);
}
///////////////////////////////////////////////////////////////////////////////
void ListAssignment::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ListAssignmentExpression", 3);
cg.printPropertyHeader("variables");
cg.printExpressionVector(m_variables);
cg.printPropertyHeader("expression");
m_array->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -131,29 +131,6 @@ TypePtr ModifierExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
return TypePtr();
}
///////////////////////////////////////////////////////////////////////////////
void ModifierExpression::outputCodeModel(CodeGenerator &cg) {
cg.printf("V:6:\"Vector\":%d:{", (int)m_modifiers.size());
for (unsigned int i = 0; i < m_modifiers.size(); i++) {
cg.printObjectHeader("Modifier", 1);
cg.printPropertyHeader("name");
switch (m_modifiers[i]) {
case T_PUBLIC: cg.printValue("public"); break;
case T_PROTECTED: cg.printValue("protected"); break;
case T_PRIVATE: cg.printValue("private"); break;
case T_STATIC: cg.printValue("static"); break;
case T_ABSTRACT: cg.printValue("abstract"); break;
case T_FINAL: cg.printValue("final"); break;
case T_ASYNC: cg.printValue("async"); break;
default:
assert(false);
}
cg.printObjectFooter();
}
cg.printf("}");
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -122,6 +122,7 @@ TypePtr NewObjectExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
if (getScope()->isFirstPass()) {
Compiler::Error(Compiler::BadConstructorCall, self);
}
m_params->setOutputCount(0);
}
m_params->inferAndCheck(ar, Type::Some, false);
}
@@ -152,25 +153,6 @@ TypePtr NewObjectExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
return Type::Object;
}
///////////////////////////////////////////////////////////////////////////////
void NewObjectExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("NewObjectExpression", m_params == nullptr ? 2 : 3);
if (m_nameExp->is(Expression::KindOfScalarExpression)) {
cg.printPropertyHeader("className");
} else {
cg.printPropertyHeader("classExpression");
}
m_nameExp->outputCodeModel(cg);
if (m_params != nullptr) {
cg.printPropertyHeader("arguments");
cg.printExpressionVector(m_params);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -146,6 +146,7 @@ void ObjectMethodExpression::setInvokeParams(AnalysisResultPtr ar) {
for (int i = 0; i < m_params->getCount(); i++) {
(*m_params)[i]->inferAndCheck(ar, Type::Variant, false);
}
m_params->resetOutputCount();
}
ExpressionPtr ObjectMethodExpression::preOptimize(AnalysisResultConstPtr ar) {
@@ -277,28 +278,6 @@ TypePtr ObjectMethodExpression::inferAndCheck(AnalysisResultPtr ar,
return checkParamsAndReturn(ar, type, coerce, func, false);
}
///////////////////////////////////////////////////////////////////////////////
void ObjectMethodExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ObjectMethodCallExpression(",
m_params == nullptr ? 3 : 4);
cg.printPropertyHeader("object");
m_object->outputCodeModel(cg);
if (m_nameExp->is(Expression::KindOfScalarExpression)) {
cg.printPropertyHeader("methodName");
} else {
cg.printPropertyHeader("methodExpression");
}
m_nameExp->outputCodeModel(cg);
if (m_params != nullptr) {
cg.printPropertyHeader("arguments");
cg.printExpressionVector(m_params);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -332,23 +332,6 @@ ObjectPropertyExpression::postOptimize(AnalysisResultConstPtr ar) {
ExpressionPtr();
}
///////////////////////////////////////////////////////////////////////////////
void ObjectPropertyExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ObjectPropertyExpression(", 3);
cg.printPropertyHeader("object");
m_object->outputCodeModel(cg);
if (m_property->is(Expression::KindOfScalarExpression)) {
cg.printPropertyHeader("propertyName");
} else {
cg.printPropertyHeader("propertyExpression");
}
m_property->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -300,45 +300,6 @@ void ParameterExpression::compatibleDefault() {
}
}
///////////////////////////////////////////////////////////////////////////////
void ParameterExpression::outputCodeModel(CodeGenerator &cg) {
auto propCount = 2;
if (m_attributeList) propCount++;
if (m_modifier != 0) propCount++;
if (m_ref) propCount++;
if (m_defaultValue != nullptr) propCount++;
cg.printObjectHeader("ParameterDeclaration(", propCount);
if (m_attributeList) {
cg.printPropertyHeader("isPassedByReference");
cg.printExpressionVector(m_attributeList);
}
if (m_modifier != 0) {
cg.printPropertyHeader("modifiers");
printf("V:6:\"Vector\":1:{");
switch (m_modifier) {
case T_PUBLIC: cg.printValue("public"); break;
case T_PROTECTED: cg.printValue("protected"); break;
case T_PRIVATE: cg.printValue("private"); break;
default: assert(false);
}
printf("}");
}
if (m_ref) {
cg.printPropertyHeader("isPassedByReference");
cg.printValue(true);
}
cg.printPropertyHeader("name");
cg.printValue(m_name);
if (m_defaultValue) {
cg.printPropertyHeader("expression");
m_defaultValue->outputCodeModel(cg);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-22
Ver Arquivo
@@ -163,28 +163,6 @@ ExpressionPtr QOpExpression::unneededHelper() {
return static_pointer_cast<Expression>(shared_from_this());
}
///////////////////////////////////////////////////////////////////////////////
void QOpExpression::outputCodeModel(CodeGenerator &cg) {
if (m_expYes == nullptr) {
cg.printObjectHeader("ValueIfNullExpression", 3);
cg.printPropertyHeader("expression");
m_condition->outputCodeModel(cg);
cg.printPropertyHeader("valueIfNull");
} else {
cg.printObjectHeader("ConditionalExpression(", 4);
cg.printPropertyHeader("condition");
m_condition->outputCodeModel(cg);
cg.printPropertyHeader("valueIfTrue");
m_expYes->outputCodeModel(cg);
cg.printPropertyHeader("valueIfFalse");
}
m_expNo->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -384,45 +384,6 @@ std::string ScalarExpression::getIdentifier() const {
return "";
}
///////////////////////////////////////////////////////////////////////////////
void ScalarExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ScalarExpression", 2);
cg.printPropertyHeader("value");
switch (m_type) {
case T_CONSTANT_ENCAPSED_STRING:
case T_ENCAPSED_AND_WHITESPACE:
case T_STRING:
case T_NUM_STRING:
cg.printValue(m_value);
break;
case T_LNUMBER:
case T_COMPILER_HALT_OFFSET:
cg.printValue((int64_t)strtoll(m_value.c_str(), nullptr, 0));
break;
case T_LINE:
cg.printValue(String(m_translated).toInt64());
break;
case T_TRAIT_C:
case T_CLASS_C:
case T_NS_C:
case T_METHOD_C:
case T_FUNC_C:
cg.printValue(m_translated);
break;
case T_DNUMBER:
cg.printValue(String(m_value).toDouble());
break;
default:
assert(false);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
void ScalarExpression::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) {
switch (m_type) {
case T_CONSTANT_ENCAPSED_STRING:
+18 -37
Ver Arquivo
@@ -102,17 +102,12 @@ SimpleFunctionCall::SimpleFunctionCall
const std::string &name, bool hadBackslash, ExpressionListPtr params,
ExpressionPtr cls)
: FunctionCall(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(SimpleFunctionCall),
ExpressionPtr(), name, hadBackslash, params, cls)
, m_type(FunType::Unknown)
, m_dynamicConstant(false)
, m_builtinFunction(false)
, m_dynamicInvoke(false)
, m_transformed(false)
, m_changedToBytecode(false)
, m_optimizable(false)
, m_safe(0)
, m_extra(nullptr)
{
ExpressionPtr(), name, hadBackslash, params, cls),
m_type(FunType::Unknown), m_dynamicConstant(false),
m_builtinFunction(false), m_fromCompiler(false),
m_dynamicInvoke(false), m_transformed(false), m_no_volatile_check(false),
m_safe(0), m_extra(nullptr) {
if (!m_class && m_className.empty()) {
m_dynamicInvoke = Option::DynamicInvokeFunctions.find(m_name) !=
Option::DynamicInvokeFunctions.end();
@@ -443,7 +438,7 @@ void SimpleFunctionCall::analyzeProgram(AnalysisResultPtr ar) {
}
case FunType::FBCallUserFuncSafe:
case FunType::FunctionExists:
{
if (!m_no_volatile_check) {
FunctionScopePtr func = ar->findFunction(Util::toLower(symbol));
if (func && func->isUserFunction()) {
func->setVolatile();
@@ -452,7 +447,7 @@ void SimpleFunctionCall::analyzeProgram(AnalysisResultPtr ar) {
}
case FunType::InterfaceExists:
case FunType::ClassExists:
{
if (!m_no_volatile_check) {
ClassScopePtr cls = ar->findClass(Util::toLower(symbol));
if (cls && cls->isUserClass()) {
cls->setVolatile();
@@ -523,7 +518,7 @@ void SimpleFunctionCall::analyzeProgram(AnalysisResultPtr ar) {
markRefParams(m_funcScope, m_name, canInvokeFewArgs());
}
} else if (ar->getPhase() == AnalysisResult::AnalyzeFinal) {
if (m_type == FunType::Unknown &&
if (!m_fromCompiler && m_type == FunType::Unknown &&
!m_class && !m_redeclared && !m_dynamicInvoke && !m_funcScope &&
(m_className.empty() ||
(m_classScope &&
@@ -575,6 +570,7 @@ void SimpleFunctionCall::updateVtFlags() {
m_name == "call_user_func_array" ||
m_name == "forward_static_call" ||
m_name == "forward_static_call_array" ||
m_name == "hphp_create_continuation" ||
m_name == "get_called_class") {
f->setNextLSB(true);
}
@@ -608,6 +604,10 @@ bool SimpleFunctionCall::isCallToFunction(const char *name) const {
!getClass() && getClassName().empty();
}
bool SimpleFunctionCall::isCompilerCallToFunction(const char *name) const {
return m_fromCompiler && isCallToFunction(name);
}
bool SimpleFunctionCall::isSimpleDefine(StringData **outName,
TypedValue *outValue) const {
if (!isCallToFunction("define")) return false;
@@ -957,7 +957,7 @@ ExpressionPtr SimpleFunctionCall::preOptimize(AnalysisResultConstPtr ar) {
}
break;
}
if (func->isUserFunction()) {
if (!m_no_volatile_check && func->isUserFunction()) {
func->setVolatile();
}
if (!func->isVolatile() && m_type == FunType::FunctionExists) {
@@ -972,7 +972,7 @@ ExpressionPtr SimpleFunctionCall::preOptimize(AnalysisResultConstPtr ar) {
for (ClassScopePtrVec::const_iterator it = classes.begin();
it != classes.end(); ++it) {
ClassScopePtr cls = *it;
if (cls->isUserClass()) {
if (!m_no_volatile_check && cls->isUserClass()) {
cls->setVolatile();
}
if (cls->isInterface()) {
@@ -996,7 +996,7 @@ ExpressionPtr SimpleFunctionCall::preOptimize(AnalysisResultConstPtr ar) {
for (ClassScopePtrVec::const_iterator it = classes.begin();
it != classes.end(); ++it) {
ClassScopePtr cls = *it;
if (cls->isUserClass()) {
if (!m_no_volatile_check && cls->isUserClass()) {
cls->setVolatile();
}
if (!cls->isInterface() && !cls->isTrait()) {
@@ -1041,6 +1041,7 @@ ExpressionPtr SimpleFunctionCall::postOptimize(AnalysisResultConstPtr ar) {
ExpressionPtr(), T_ARRAY, true));
return replaceValue(rep);
}
m_params->resetOutputCount();
}
/*
Dont do this for now. Need to take account of newly created
@@ -1273,26 +1274,6 @@ TypePtr SimpleFunctionCall::inferAndCheck(AnalysisResultPtr ar, TypePtr type,
return rtype;
}
///////////////////////////////////////////////////////////////////////////////
void SimpleFunctionCall::outputCodeModel(CodeGenerator &cg) {
if (m_class || !m_className.empty()) {
cg.printObjectHeader("ClassMethodCallExpression", 4);
cg.printPropertyHeader("className");
StaticClassName::outputCodeModel(cg);
cg.printPropertyHeader("methodName");
} else {
cg.printObjectHeader("SimpleFunctionCallExpression", 3);
cg.printPropertyHeader("functionName");
}
m_nameExp->outputCodeModel(cg);
cg.printPropertyHeader("arguments");
cg.printExpressionVector(m_params);
cg.printPropertyHeader("location");
cg.printLocation(m_nameExp->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
+5 -24
Ver Arquivo
@@ -40,14 +40,9 @@ public:
bool isDefineWithoutImpl(AnalysisResultConstPtr ar);
void setValid() { m_valid = true; }
void setFromCompiler() { m_fromCompiler = true; }
void setThrowFatal() { m_type = FunType::ThrowFatal; }
void setThrowParseFatal() { m_type = FunType::ThrowParseFatal; }
bool isParseFatalFunction() const {
return m_type == FunType::ThrowParseFatal;
}
bool isFatalFunction() const {
return isParseFatalFunction() || m_type == FunType::ThrowFatal;
}
int isFatalFunction() const { return m_type == FunType::ThrowFatal; }
int isStaticCompact() const { return m_type == FunType::StaticCompact; }
// define(<literal-string>, <scalar>);
@@ -77,21 +72,8 @@ public:
void updateVtFlags();
void setLocalThis(const std::string &name) { m_localThis = name; }
bool isCallToFunction(const char *name) const;
bool isCompilerCallToFunction(const char *name) const;
void resolveNSFallbackFunc(AnalysisResultConstPtr ar, FileScopePtr fs);
void setOptimizable() {
m_optimizable = true;
}
bool isOptimizable() const {
return m_optimizable;
}
void changeToBytecode() {
m_changedToBytecode = true;
}
virtual bool allowCellByRef() const override {
return m_changedToBytecode;
}
protected:
enum class FunType {
Unknown,
@@ -111,7 +93,6 @@ protected:
GetDefinedVars,
FBCallUserFuncSafe,
ThrowFatal,
ThrowParseFatal,
ClassAlias,
};
@@ -119,11 +100,11 @@ protected:
FunType m_type;
unsigned m_dynamicConstant : 1;
unsigned m_builtinFunction : 1;
unsigned m_fromCompiler : 1;
unsigned m_invokeFewArgsDecision : 1;
unsigned m_dynamicInvoke : 1;
unsigned m_transformed : 1;
unsigned m_changedToBytecode : 1; // true if it morphed into a bytecode
unsigned m_optimizable : 1; // true if it can be morphed into a bytecode
unsigned m_no_volatile_check : 1;
int m_safe;
ExpressionPtr m_safeDef;
-11
Ver Arquivo
@@ -307,17 +307,6 @@ TypePtr SimpleVariable::inferAndCheck(AnalysisResultPtr ar, TypePtr type,
return actual;
}
///////////////////////////////////////////////////////////////////////////////
void SimpleVariable::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("SimpleVariableExpression", 2);
cg.printPropertyHeader("variableName");
cg.printValue(m_name);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -167,20 +167,6 @@ bool StaticClassName::checkPresent() {
///////////////////////////////////////////////////////////////////////////////
void StaticClassName::outputCodeModel(CodeGenerator &cg) {
if (isSelf()) {
cg.printf("self");
} else if (isParent()) {
cg.printf("parent");
} else if (isStatic()) {
cg.printf("static");
} else {
cg.printf("%s", m_origClassName.c_str());
}
}
///////////////////////////////////////////////////////////////////////////////
void StaticClassName::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) {
if (m_class) {
m_class->outputPHP(cg, ar);
@@ -56,7 +56,6 @@ protected:
std::string m_className;
void updateClassName();
void outputCodeModel(CodeGenerator &cg);
void outputPHP(CodeGenerator &cg, AnalysisResultPtr ar);
private:
unsigned m_self : 1;
@@ -337,22 +337,6 @@ bool StaticMemberExpression::canonCompare(ExpressionPtr e) const {
return m_className == s->m_className;
}
///////////////////////////////////////////////////////////////////////////////
void StaticMemberExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ClassPropertyExpression", 2);
cg.printPropertyHeader("className");
StaticClassName::outputCodeModel(cg);
if (m_exp->is(Expression::KindOfScalarExpression)) {
cg.printPropertyHeader("propertyName");
} else {
cg.printPropertyHeader("propertyExpression");
}
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -20,7 +20,6 @@
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/code_model_enums.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/analysis/function_scope.h"
@@ -568,80 +567,6 @@ ExpressionPtr UnaryOpExpression::unneededHelper() {
return static_pointer_cast<Expression>(shared_from_this());
}
///////////////////////////////////////////////////////////////////////////////
void UnaryOpExpression::outputCodeModel(CodeGenerator &cg) {
switch (m_op) {
case T_UNSET:
case T_EXIT:
case T_ARRAY:
case T_ISSET:
case T_EMPTY:
case T_EVAL: {
cg.printObjectHeader("SimpleFunctionCallExpression", 3);
std::string funcName;
switch (m_op) {
case T_UNSET: funcName = "unset"; break;
case T_EXIT: funcName = "exit"; break;
case T_ARRAY: funcName = "array"; break;
case T_ISSET: funcName = "isset"; break;
case T_EMPTY: funcName = "empty"; break;
case T_EVAL: funcName = "eval"; break;
default: break;
}
cg.printPropertyHeader("functionName");
cg.printValue(funcName);
cg.printPropertyHeader("arguments");
printf("V:6:\"Vector\":1:{");
m_exp->outputCodeModel(cg);
printf("}");
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
return;
}
default:
break;
}
cg.printObjectHeader("UnaryOpExpression", 3);
cg.printPropertyHeader("expression");
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("operation");
int op = 0;
switch (m_op) {
case T_CLONE: op = PHP_CLONE_OP; break;
case T_INC:
op = m_front ? PHP_PRE_INCREMENT_OP : PHP_POST_INCREMENT_OP;
break;
case T_DEC:
op = m_front ? PHP_PRE_DECREMENT_OP : PHP_POST_DECREMENT_OP;
break;
case '+': op = PHP_PLUS_OP; break;
case '-': op = PHP_MINUS_OP; break;
case '!': op = PHP_NOT_OP; break;
case '~': op = PHP_BITWISE_NOT_OP; break;
case T_INT_CAST: op = PHP_INT_CAST_OP; break;
case T_DOUBLE_CAST: op = PHP_FLOAT_CAST_OP; break;
case T_STRING_CAST: op = PHP_STRING_CAST_OP; break;
case T_ARRAY_CAST: op = PHP_ARRAY_CAST_OP; break;
case T_OBJECT_CAST: op = PHP_OBJECT_CAST_OP; break;
case T_BOOL_CAST: op = PHP_BOOL_CAST_OP; break;
case T_UNSET_CAST: op = PHP_UNSET_CAST_OP; break;
case '@': op = PHP_ERROR_CONTROL_OP; break;
case T_INCLUDE: op = PHP_INCLUDE_OP; break;
case T_INCLUDE_ONCE: op = PHP_INCLUDE_ONCE_OP; break;
case T_REQUIRE: op = PHP_REQUIRE_OP; break;
case T_REQUIRE_ONCE: op = PHP_REQUIRE_ONCE_OP; break;
default:
assert(false);
}
cg.printValue(op);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-33
Ver Arquivo
@@ -15,17 +15,10 @@
*/
#include "hphp/compiler/expression/user_attribute.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/parser/scanner.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
DECLARE_BOOST_TYPES(Expression);
DECLARE_BOOST_TYPES(ExpressionList);
DECLARE_BOOST_TYPES(UnaryOpExpression);
// constructors/destructors
UserAttribute::UserAttribute
@@ -58,32 +51,6 @@ TypePtr UserAttribute::inferTypes(AnalysisResultPtr ar, TypePtr type,
return TypePtr();
}
///////////////////////////////////////////////////////////////////////////////
void UserAttribute::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("CodeAttribute", m_exp != nullptr ? 3 : 2);
cg.printPropertyHeader("attributeName");
cg.printValue(m_name);
if (m_exp != nullptr && m_exp->is(Expression::KindOfUnaryOpExpression)) {
UnaryOpExpressionPtr u(static_pointer_cast<UnaryOpExpression>(m_exp));
if (u->getOp() == T_ARRAY) {
ExpressionPtr ex = u->getExpression();
if (ex->is(Expression::KindOfExpressionList)) {
ExpressionListPtr el(static_pointer_cast<ExpressionList>(ex));
cg.printPropertyHeader("expressions");
cg.printExpressionVector(el);
} else {
assert(false);
}
} else {
assert(false);
}
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
+1 -15
Ver Arquivo
@@ -50,6 +50,7 @@ void YieldExpression::analyzeProgram(AnalysisResultPtr ar) {
if (m_keyExp) {
m_keyExp->analyzeProgram(ar);
}
m_valExp->setChildOfYield();
m_valExp->analyzeProgram(ar);
m_label.setNew();
@@ -95,21 +96,6 @@ TypePtr YieldExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
return Type::Variant;
}
///////////////////////////////////////////////////////////////////////////////
void YieldExpression::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("YieldExpression", m_keyExp != nullptr ? 3 : 2);
cg.printPropertyHeader("expression");
if (m_keyExp != nullptr) {
cg.printPropertyHeader("key");
m_keyExp->outputCodeModel(cg);
}
cg.printPropertyHeader("value");
m_valExp->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
+11 -2
Ver Arquivo
@@ -118,6 +118,7 @@ bool Option::EnableHipHopExperimentalSyntax = false;
bool Option::EnableShortTags = true;
bool Option::EnableAspTags = false;
bool Option::EnableXHP = false;
bool Option::EnableFinallyStatement = false;
int Option::ParserThreadCount = 0;
int Option::GetScannerType() {
@@ -130,7 +131,10 @@ int Option::GetScannerType() {
}
int Option::InvokeFewArgsCount = 6;
bool Option::InvokeWithSpecificArgs = true;
bool Option::FlattenInvoke = true;
int Option::InlineFunctionThreshold = -1;
bool Option::UseVirtualDispatch = false;
bool Option::EliminateDeadCode = true;
bool Option::CopyProp = false;
bool Option::LocalCopyProp = true;
@@ -141,7 +145,6 @@ bool Option::VariableCoalescing = false;
bool Option::ArrayAccessIdempotent = false;
bool Option::DumpAst = false;
bool Option::WholeProgram = true;
bool Option::UseHHBBC = getenv("HHVM_HHBBC");
bool Option::RecordErrors = true;
std::string Option::DocJson;
@@ -150,6 +153,8 @@ bool Option::AllVolatile = false;
StringBag Option::OptionStrings;
bool Option::GenerateCppLibCode = false;
bool Option::GenerateSourceInfo = false;
bool Option::GenerateDocComments = true;
void (*Option::m_hookHandler)(Hdf &config);
@@ -278,11 +283,16 @@ void Option::Load(Hdf &config) {
ParserThreadCount = Process::GetCPUCount();
}
EnableFinallyStatement = config["EnableFinallyStatement"].getBool();
EnableEval = (EvalLevel)config["EnableEval"].getByte(0);
AllDynamic = config["AllDynamic"].getBool(true);
AllVolatile = config["AllVolatile"].getBool();
GenerateCppLibCode = config["GenerateCppLibCode"].getBool(false);
GenerateSourceInfo = config["GenerateSourceInfo"].getBool(false);
GenerateDocComments = config["GenerateDocComments"].getBool(true);
UseVirtualDispatch = config["UseVirtualDispatch"].getBool(false);
EliminateDeadCode = config["EliminateDeadCode"].getBool(true);
CopyProp = config["CopyProp"].getBool(false);
LocalCopyProp = config["LocalCopyProp"].getBool(true);
@@ -293,7 +303,6 @@ void Option::Load(Hdf &config) {
ArrayAccessIdempotent = config["ArrayAccessIdempotent"].getBool(false);
DumpAst = config["DumpAst"].getBool(false);
WholeProgram = config["WholeProgram"].getBool(true);
UseHHBBC = config["UseHHBBC"].getBool(UseHHBBC);
// Temporary, during file-cache migration.
FileCache::UseNewCache = config["UseNewCache"].getBool(false);
+6 -1
Ver Arquivo
@@ -222,6 +222,7 @@ public:
static bool EnableShortTags;
static bool EnableAspTags;
static bool EnableXHP;
static bool EnableFinallyStatement;
static int ParserThreadCount;
static int GetScannerType();
@@ -237,7 +238,10 @@ public:
* Optimizations
*/
static int InvokeFewArgsCount;
static bool InvokeWithSpecificArgs;
static bool FlattenInvoke;
static int InlineFunctionThreshold;
static bool UseVirtualDispatch;
static bool EliminateDeadCode;
static bool CopyProp;
static bool LocalCopyProp;
@@ -248,12 +252,13 @@ public:
/**
* Output options
*/
static bool GenerateCppLibCode;
static bool GenerateSourceInfo;
static bool GenerateDocComments;
static bool ControlFlow;
static bool VariableCoalescing;
static bool DumpAst;
static bool WholeProgram;
static bool UseHHBBC; // see hhbbc/README
static bool RecordErrors;
static std::string DocJson; // filename to dump doc JSON to
+5 -4
Ver Arquivo
@@ -193,14 +193,14 @@ FileCachePtr Package::getFileCache() {
///////////////////////////////////////////////////////////////////////////////
class ParserWorker :
public JobQueueWorker<std::pair<const char *,bool>, Package*, true, true> {
public JobQueueWorker<std::pair<const char *,bool>, true, true> {
public:
bool m_ret;
ParserWorker() : m_ret(true) {}
virtual void doJob(JobType job) {
bool ret;
try {
Package *package = m_context;
Package *package = (Package*)m_opaque;
ret = package->parseImpl(job.first);
} catch (Exception &e) {
Logger::Error("%s", e.getMessage().c_str());
@@ -222,7 +222,8 @@ void Package::addSourceFile(const char *fileName, bool check /* = false */) {
Lock lock(m_mutex);
bool inserted = m_filesToParse.insert(Util::canonicalize(fileName)).second;
if (inserted && m_dispatcher) {
((JobQueueDispatcher<ParserWorker>*)m_dispatcher)->enqueue(
((JobQueueDispatcher<ParserWorker::JobType,
ParserWorker>*)m_dispatcher)->enqueue(
std::make_pair(m_files.add(fileName), check));
}
}
@@ -239,7 +240,7 @@ bool Package::parse(bool check) {
}
if (threadCount <= 0) threadCount = 1;
JobQueueDispatcher<ParserWorker>
JobQueueDispatcher<ParserWorker::JobType, ParserWorker>
dispatcher(threadCount, true, 0, false, this);
m_dispatcher = &dispatcher;
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+30 -178
Ver Arquivo
@@ -100,17 +100,13 @@
#endif
#define NEW_EXP0(cls) \
cls##Ptr(new cls(BlockScopePtr(), \
getLocation()))
cls##Ptr(new cls(BlockScopePtr(), getLocation()))
#define NEW_EXP(cls, e...) \
cls##Ptr(new cls(BlockScopePtr(), \
getLocation(), ##e))
cls##Ptr(new cls(BlockScopePtr(), getLocation(), ##e))
#define NEW_STMT0(cls) \
cls##Ptr(new cls(BlockScopePtr(), getLabelScope(), \
getLocation()))
cls##Ptr(new cls(BlockScopePtr(), getLocation()))
#define NEW_STMT(cls, e...) \
cls##Ptr(new cls(BlockScopePtr(), getLabelScope(), \
getLocation(), ##e))
cls##Ptr(new cls(BlockScopePtr(), getLocation(), ##e))
#define PARSE_ERROR(fmt, args...) HPHP_PARSER_ERROR(fmt, this, ##args)
@@ -155,8 +151,7 @@ StatementListPtr Parser::ParseString(const String& input, AnalysisResultPtr ar,
Parser::Parser(Scanner &scanner, const char *fileName,
AnalysisResultPtr ar, int fileSize /* = 0 */)
: ParserBase(scanner, fileName), m_ar(ar), m_lambdaMode(false),
m_closureGenerator(false), m_nsState(SeenNothing),
m_aliasTable(getAutoAliasedClasses(), [&] { return isAutoAliasOn(); }) {
m_closureGenerator(false), m_nsState(SeenNothing) {
string md5str = Eval::FileRepository::unitMd5(scanner.getMd5());
MD5 md5 = MD5(md5str.c_str());
@@ -179,16 +174,10 @@ bool Parser::parse() {
"Parse error: %s",
errString().c_str());
}
return true;
} catch (const ParseTimeFatalException& e) {
m_file->cleanupForError(m_ar);
if (e.m_parseFatal) {
m_file->makeParseFatal(m_ar, e.getMessage(), e.m_line);
} else {
m_file->makeFatal(m_ar, e.getMessage(), e.m_line);
}
return false;
} catch (ParseTimeFatalException &e) {
m_file->cleanupForError(m_ar, e.m_line, e.getMessage());
}
return true;
}
void Parser::error(const char* fmt, ...) {
@@ -201,22 +190,19 @@ void Parser::error(const char* fmt, ...) {
fatal(&m_loc, msg.c_str());
}
void Parser::parseFatal(const Location* loc, const char* msg) {
// we can't use loc->file, as the bison parser doesn't track that in YYLTYPE
auto file = m_file->getName().c_str();
auto exn = ParseTimeFatalException(file, loc->line0, "%s", msg);
exn.setParseFatal();
throw exn;
}
void Parser::fatal(const Location* loc, const char* msg) {
throw ParseTimeFatalException(loc->file, loc->line0, "%s", msg);
void Parser::fatal(Location *loc, const char *msg) {
throw ParseTimeFatalException(loc->file, loc->line0,
"%s", msg);
}
string Parser::errString() {
return m_error.empty() ? getMessage() : m_error;
}
bool Parser::enableFinallyStatement() {
return Option::EnableFinallyStatement;
}
void Parser::pushComment() {
m_comments.push_back(m_scanner.detachDocComment());
}
@@ -249,39 +235,6 @@ void Parser::completeScope(BlockScopePtr inner) {
}
}
LabelScopePtr Parser::getLabelScope() const {
DCHECK(!m_labelScopes.empty());
DCHECK(!m_labelScopes.back().empty());
DCHECK(m_labelScopes.back().back() != nullptr);
return m_labelScopes.back().back();
}
void Parser::onNewLabelScope(bool fresh) {
if (fresh) {
m_labelScopes.push_back(LabelScopePtrVec());
}
DCHECK(!m_labelScopes.empty());
LabelScopePtr labelScope(new LabelScope());
m_labelScopes.back().push_back(labelScope);
}
void Parser::onScopeLabel(const Token& stmt, const Token& label) {
DCHECK(!m_labelScopes.empty());
DCHECK(!m_labelScopes.back().empty());
for (auto& scope : m_labelScopes.back()) {
scope->addLabel(stmt.stmt, label.text());
}
}
void Parser::onCompleteLabelScope(bool fresh) {
assert(!m_labelScopes.empty());
assert(!m_labelScopes.back().empty());
m_labelScopes.back().pop_back();
if (fresh) {
m_labelScopes.pop_back();
}
}
///////////////////////////////////////////////////////////////////////////////
// variables
@@ -420,7 +373,7 @@ void Parser::onCallParam(Token &out, Token *params, Token &expr, bool ref) {
}
void Parser::onCall(Token &out, bool dynamic, Token &name, Token &params,
Token *cls) {
Token *cls, bool fromCompiler) {
ExpressionPtr clsExp;
if (cls) {
clsExp = cls->exp;
@@ -429,6 +382,7 @@ void Parser::onCall(Token &out, bool dynamic, Token &name, Token &params,
out->exp = NEW_EXP(DynamicFunctionCall, name->exp,
dynamic_pointer_cast<ExpressionList>(params->exp),
clsExp);
assert(!fromCompiler);
} else {
const string &s = name.text();
// strip out namespaces for func_get_args and friends check
@@ -448,13 +402,8 @@ void Parser::onCall(Token &out, bool dynamic, Token &name, Token &params,
(new RealSimpleFunctionCall
(BlockScopePtr(), getLocation(), name->text(), name->num() & 2,
dynamic_pointer_cast<ExpressionList>(params->exp), clsExp));
if (m_scanner.isHHSyntaxEnabled() && !(name->num() & 2)) {
// If the function name is without any backslashes or
// namespace qualification then we treat this as a candidate
// for optimization via bytecode promotion.
// "idx" is the only function in that class for now but it's
// cheaper to set the bit that to check for the function name
call->setOptimizable();
if (fromCompiler) {
call->setFromCompiler();
}
out->exp = call;
@@ -944,7 +893,7 @@ StatementPtr Parser::onFunctionHelper(FunctionType type,
StatementListPtr stmts = stmt->stmt || stmt->num() != 1 ?
dynamic_pointer_cast<StatementList>(stmt->stmt)
: NEW_STMT0(StatementList);
: NEW_EXP0(StatementList);
ExpressionListPtr old_params =
dynamic_pointer_cast<ExpressionList>(params->exp);
@@ -1048,8 +997,7 @@ void Parser::onParam(Token &out, Token *params, Token &type, Token &var,
void Parser::onClassStart(int type, Token &name) {
const Type::TypePtrMap& typeHintTypes =
Type::GetTypeHintTypes(m_scanner.isHHSyntaxEnabled());
if (0 == strcasecmp("self", name.text().c_str()) ||
0 == strcasecmp("parent", name.text().c_str()) ||
if (name.text() == "self" || name.text() == "parent" ||
typeHintTypes.find(name.text()) != typeHintTypes.end()) {
PARSE_ERROR("Cannot use '%s' as class name as it is reserved",
name.text().c_str());
@@ -1670,18 +1618,12 @@ void Parser::onTry(Token &out, Token &tryStmt, Token &className, Token &var,
out->stmt = NEW_STMT(TryStatement, tryStmt->stmt,
dynamic_pointer_cast<StatementList>(stmtList),
finallyStmt->stmt);
if (tryStmt->stmt) {
out->stmt->setLabelScope(stmtList->getLabelScope());
}
}
void Parser::onTry(Token &out, Token &tryStmt, Token &finallyStmt) {
out->stmt = NEW_STMT(TryStatement, tryStmt->stmt,
dynamic_pointer_cast<StatementList>(NEW_STMT0(StatementList)),
finallyStmt->stmt);
if (tryStmt->stmt) {
out->stmt->setLabelScope(tryStmt->stmt->getLabelScope());
}
}
void Parser::onCatch(Token &out, Token &catches, Token &className, Token &var,
@@ -1699,11 +1641,6 @@ void Parser::onCatch(Token &out, Token &catches, Token &className, Token &var,
void Parser::onFinally(Token &out, Token &stmt) {
out->stmt = NEW_STMT(FinallyStatement, stmt->stmt);
// TODO (#3271396) This can be greatly improved. In particular
// even when a finally block exists inside a function it is often
// the case that the unnamed locals state & ret are not needed.
// See task description for further details.
m_file->setAttribute(FileScope::NeedsFinallyLocals);
}
void Parser::onThrow(Token &out, Token &expr) {
@@ -1825,86 +1762,6 @@ void Parser::onTypeSpecialization(Token& type, char specialization) {
///////////////////////////////////////////////////////////////////////////////
// namespace support
//////////////////// AliasTable /////////////////////
Parser::AliasTable::AliasTable(const std::vector<AliasEntry>& autoAliases,
std::function<bool ()> autoOracle) :
m_autoAliases(autoAliases), m_autoOracle(autoOracle),
m_alreadyImported(false) {
if (!m_autoOracle) {
setFalseOracle();
}
}
void Parser::AliasTable::setFalseOracle() {
m_autoOracle = [] () { return false; };
}
/*
* Add the auto-imports to the map.
* This is called by all the other operations, so the auto-import occurs
* on-demand.
*/
void Parser::AliasTable::addAutoImports() {
if (!m_alreadyImported && m_autoOracle()) {
m_alreadyImported = true;
for (auto entry : m_autoAliases) {
m_aliases[entry.alias] = (NameEntry){entry.name, true};
}
}
}
std::string Parser::AliasTable::getName(std::string alias) {
addAutoImports();
auto it = m_aliases.find(alias);
return (m_aliases.end() == it) ? "" : it->second.name;
}
bool Parser::AliasTable::isAliased(std::string alias) {
addAutoImports();
return m_aliases.find(alias) != m_aliases.end();
}
bool Parser::AliasTable::isAutoImported(std::string alias) {
addAutoImports();
auto it = m_aliases.find(alias);
return it != m_aliases.end() && it->second.isAuto;
}
void Parser::AliasTable::map(std::string alias, std::string name) {
addAutoImports();
m_aliases[alias] = (NameEntry){name, false};
}
/*
* To be called when we enter a fresh namespace.
*/
void Parser::AliasTable::clear() {
m_aliases.clear();
m_alreadyImported = false;
}
//////////////////////////////////////////////////////
/*
* We auto-alias classes on HH mode and only if we're in the global namespace.
*/
bool Parser::isAutoAliasOn() {
return m_scanner.isHHSyntaxEnabled() && ("" == m_namespace);
}
std::vector<Parser::AliasTable::AliasEntry> Parser::getAutoAliasedClasses() {
std::vector<AliasTable::AliasEntry> aliases;
aliases.push_back(
(AliasTable::AliasEntry){"Traversable", "HH\\Traversable"});
aliases.push_back(
(AliasTable::AliasEntry){"Iterator", "HH\\Iterator"});
return aliases;
}
void Parser::nns(int token) {
if (m_nsState == SeenNamespaceStatement && token != ';') {
error("No code may exist outside of namespace {}: %s",
@@ -1930,9 +1787,10 @@ void Parser::onNamespaceStart(const std::string &ns,
m_nsState = InsideNamespace;
m_nsFileScope = file_scope;
m_aliases.clear();
pushComment();
m_namespace = ns;
m_aliasTable.clear();
}
void Parser::onNamespaceEnd() {
@@ -1949,17 +1807,12 @@ void Parser::onUse(const std::string &ns, const std::string &as) {
key = ns.substr(pos + 1);
}
}
// It's not an error if the alias already exists but is auto-imported.
// In that case, it gets replaced.
if (m_aliasTable.isAliased(key) && !m_aliasTable.isAutoImported(key) &&
m_aliasTable.getName(key) != ns) {
if (m_aliases.find(key) != m_aliases.end() && m_aliases[key] != ns) {
error("Cannot use %s as %s because the name is already in use: %s",
ns.c_str(), key.c_str(), getMessage().c_str());
return;
}
m_aliasTable.map(key, ns);
m_aliases[key] = ns;
}
std::string Parser::nsDecl(const std::string &name) {
@@ -1976,16 +1829,15 @@ std::string Parser::resolve(const std::string &ns, bool cls) {
alias = ns.substr(0, pos);
}
if (m_aliasTable.isAliased(alias)) {
auto name = m_aliasTable.getName(alias);
hphp_string_imap<std::string>::const_iterator iter = m_aliases.find(alias);
if (iter != m_aliases.end()) {
// Was it a namespace alias?
if (pos != string::npos) {
return name + ns.substr(pos);
return iter->second + ns.substr(pos);
}
// Only classes can appear directly in "use" statements
if (cls) {
return name;
return iter->second;
}
}
@@ -2050,7 +1902,7 @@ void Parser::registerAlias(std::string name) {
size_t pos = name.rfind(NAMESPACE_SEP);
if (pos != string::npos) {
string key = name.substr(pos + 1);
m_aliasTable.map(key, name);
m_aliases[key] = name;
}
}
+14 -95
Ver Arquivo
@@ -17,8 +17,6 @@
#ifndef incl_HPHP_COMPILER_PARSER_H_
#define incl_HPHP_COMPILER_PARSER_H_
#include <functional>
#include "hphp/runtime/base/exceptions.h"
#include "hphp/parser/parser.h"
#include "hphp/compiler/construct.h"
@@ -28,26 +26,24 @@
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/util/logger.h"
#ifdef HPHP_PARSER_NS
#undef HPHP_PARSER_NS
#endif
#define HPHP_PARSER_NS Compiler
#define LOG_PARSE_ERROR(file, line, fmt, args...) \
HPHP::Logger::Error( \
"HipHop Fatal error: " fmt " in %s on line %d", \
##args, \
(file), \
(line) \
)
#ifdef HPHP_PARSER_ERROR
#undef HPHP_PARSER_ERROR
#endif
#define HPHP_PARSER_ERROR(fmt, p, args...) \
throw HPHP::ParseTimeFatalException((p)->file(), (p)->line1(), fmt, ##args)
#define HPHP_PARSER_ERROR(fmt, p, args...) \
do { \
if (HPHP::Option::WholeProgram) { \
HPHP::Logger::Error(fmt " %s", ##args, (p)->getMessage(true).c_str()); \
} \
throw HPHP::ParseTimeFatalException((p)->file(), (p)->line1(), \
fmt, ##args); \
} while (0)
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -55,7 +51,6 @@ namespace HPHP {
DECLARE_BOOST_TYPES(Expression);
DECLARE_BOOST_TYPES(Statement);
DECLARE_BOOST_TYPES(StatementList);
DECLARE_BOOST_TYPES(LabelScope);
DECLARE_BOOST_TYPES(Location);
DECLARE_BOOST_TYPES(AnalysisResult);
DECLARE_BOOST_TYPES(BlockScope);
@@ -127,10 +122,10 @@ public:
virtual bool parseImpl();
bool parse();
virtual void error(const char* fmt, ...) ATTRIBUTE_PRINTF(2,3);
virtual bool enableFinallyStatement();
IMPLEMENT_XHP_ATTRIBUTES;
virtual void fatal(const Location* loc, const char* msg);
virtual void parseFatal(const Location* loc, const char* msg);
virtual void fatal(Location *loc, const char *msg);
std::string errString();
// result
@@ -159,7 +154,8 @@ public:
void onStaticMember(Token &out, Token &cls, Token &name);
void onRefDim(Token &out, Token &var, Token &offset);
void onCallParam(Token &out, Token *params, Token &expr, bool ref);
void onCall(Token &out, bool dynamic, Token &name, Token &params, Token *cls);
void onCall(Token &out, bool dynamic, Token &name, Token &params,
Token *cls, bool fromCompiler = false);
void onEncapsList(Token &out, int type, Token &list);
void addEncap(Token &out, Token *list, Token &expr, int type);
void encapRefDim(Token &out, Token &var, Token &offset);
@@ -275,36 +271,6 @@ public:
std::string nsDecl(const std::string &name);
std::string resolve(const std::string &ns, bool cls);
/*
* Get the current label scope. A new label scope is demarcated by
* one of the following: a loop, a switch statement, a finally block,
* a try block or one of the constructs demarcating variables scopes
* (i.e. functions, closures, etc.)
* For every label scope, we keep track of the labels
* that are available inside it. This is required for supporting
* features such as try ... finally.
*/
LabelScopePtr getLabelScope() const;
/*
* Called whenever a new label scope is entered. The fresh parameter
* indicates whether the scope is also a variable scope (i.e. a
* function, a closure, ...) or just a label scope (i.e. a loop body,
* a switch statement, a finally block, ...).
*/
void onNewLabelScope(bool fresh);
/*
* Called whenever a new label is encountered.
*/
void onScopeLabel(const Token& stmt, const Token& label);
/*
* Called whenever a label scope ends. The fresh parameter has the
* same meaning as for onNewLabelScope.
*/
void onCompleteLabelScope(bool fresh);
virtual void invalidateGoto(TStatementPtr stmt, GotoError error);
virtual void invalidateLabel(TStatementPtr stmt);
@@ -339,7 +305,6 @@ private:
FileScopePtr m_file;
std::vector<std::string> m_comments; // for docComment stack
std::vector<BlockScopePtrVec> m_scopes;
std::vector<LabelScopePtrVec> m_labelScopes;
std::vector<FunctionContext> m_funcContexts;
std::vector<std::vector<StatementPtr> > m_prependingStatements;
std::vector<ScalarExpressionPtr> m_compilerHaltOffsetVec;
@@ -401,57 +366,11 @@ private:
SeenNamespaceStatement,
InsideNamespace,
};
/*
* An AliasTable maps aliases to names.
* We use it instead a regular map because it lazily imports a bunch of
* names into the current namespace when appropriate.
*/
class AliasTable {
public:
struct AliasEntry {
std::string alias;
std::string name;
};
AliasTable(const std::vector<AliasEntry>& autoAliases,
std::function<bool ()> autoOracle);
std::string getName(std::string alias);
bool isAliased(std::string alias);
bool isAutoImported(std::string alias);
void map(std::string alias, std::string name);
void clear();
private:
struct NameEntry {
std::string name;
bool isAuto; // Is the name automatically-imported?
};
hphp_string_imap<NameEntry> m_aliases;
// These get imported every time we enter a new namespace.
std::vector<AliasEntry> m_autoAliases;
// Returns true if stuff should be auto-imported.
std::function<bool ()> m_autoOracle;
// Have we already auto-imported names for the current namespace?
// This is useful because auto-imports are done lazily.
bool m_alreadyImported;
void setFalseOracle();
void addAutoImports();
};
NamespaceState m_nsState;
bool m_nsFileScope;
std::string m_namespace; // current namespace
AliasTable m_aliasTable;
hphp_string_imap<std::string> m_aliases;
void registerAlias(std::string name);
bool isAutoAliasOn();
std::vector<AliasTable::AliasEntry> getAutoAliasedClasses();
};
///////////////////////////////////////////////////////////////////////////////
-13
Ver Arquivo
@@ -93,19 +93,6 @@ void BlockStatement::inferTypes(AnalysisResultPtr ar) {
if (m_stmts) m_stmts->inferTypes(ar);
}
///////////////////////////////////////////////////////////////////////////////
void BlockStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("BlockStatement", m_stmts != nullptr ? 2 : 1);
if (m_stmts != nullptr) {
cg.printPropertyHeader("statements");
m_stmts->outputCodeModel(cg);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-15
Ver Arquivo
@@ -75,21 +75,6 @@ StatementPtr BreakStatement::preOptimize(AnalysisResultConstPtr ar) {
void BreakStatement::inferTypes(AnalysisResultPtr ar) {
}
///////////////////////////////////////////////////////////////////////////////
void BreakStatement::outputCodeModel(CodeGenerator &cg) {
if (strncmp(m_name, "break", 5)) {
cg.printObjectHeader("BreakStatement", 2);
} else {
cg.printObjectHeader("ContinueStatement", 2);
}
cg.printPropertyHeader("depth");
cg.printValue((int)m_depth);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-20
Ver Arquivo
@@ -118,26 +118,6 @@ void CaseStatement::inferAndCheck(AnalysisResultPtr ar, TypePtr type,
if (m_stmt) m_stmt->inferTypes(ar);
}
///////////////////////////////////////////////////////////////////////////////
void CaseStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 1;
if (m_condition != nullptr) numProps++;
if (m_stmt != nullptr) numProps++;
cg.printObjectHeader("CaseStatement", numProps);
if (m_condition != nullptr) {
cg.printPropertyHeader("condition");
m_condition->outputCodeModel(cg);
}
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-19
Ver Arquivo
@@ -134,25 +134,6 @@ void CatchStatement::inferTypes(AnalysisResultPtr ar) {
if (m_stmt) m_stmt->inferTypes(ar);
}
///////////////////////////////////////////////////////////////////////////////
void CatchStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 3;
if (m_stmt != nullptr) numProps++;
cg.printObjectHeader("CatchStatement", numProps);
cg.printPropertyHeader("className");
cg.printValue(m_origClassName);
cg.printPropertyHeader("variableName");
cg.printValue(m_variable->getName());
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-11
Ver Arquivo
@@ -130,17 +130,6 @@ void ClassConstant::inferTypes(AnalysisResultPtr ar) {
m_exp->inferAndCheck(ar, Type::Some, false);
}
///////////////////////////////////////////////////////////////////////////////
void ClassConstant::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ConstantStatement", 2);
cg.printPropertyHeader("expressions");
cg.printExpressionVector(m_exp);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-54
Ver Arquivo
@@ -31,7 +31,6 @@
#include "hphp/util/util.h"
#include "hphp/compiler/statement/interface_statement.h"
#include "hphp/compiler/statement/use_trait_statement.h"
#include "hphp/compiler/code_model_enums.h"
#include "hphp/compiler/option.h"
#include <sstream>
#include <algorithm>
@@ -212,59 +211,6 @@ void ClassStatement::analyzeProgram(AnalysisResultPtr ar) {
void ClassStatement::inferTypes(AnalysisResultPtr ar) {
}
///////////////////////////////////////////////////////////////////////////////
void ClassStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 4;
if (m_attrList != nullptr) numProps++;
if (m_type == T_ABSTRACT || m_type == T_FINAL) numProps++;
if (!m_parent.empty()) numProps++;
if (m_base != nullptr) numProps++;
if (m_stmt != nullptr) numProps++;
if (!m_docComment.empty()) numProps++;
cg.printObjectHeader("TypeStatement", numProps);
if (m_attrList != nullptr) {
cg.printPropertyHeader("attributes");
cg.printExpressionVector(m_attrList);
}
if (m_type == T_ABSTRACT) {
cg.printPropertyHeader("modifiers");
cg.printModifierVector("abstract");
} else if (m_type == T_FINAL) {
cg.printPropertyHeader("modifiers");
cg.printModifierVector("final");
}
cg.printPropertyHeader("kind");
if (m_type == T_TRAIT) {
cg.printValue(PHP_TRAIT);
} else {
cg.printValue(PHP_CLASS);
}
cg.printPropertyHeader("name");
cg.printValue(m_originalName);
//TODO: type parameters (task 3262469)
if (!m_parent.empty()) {
cg.printPropertyHeader("baseClass");
cg.printTypeExpression(m_originalParent);
}
if (m_base != nullptr) {
cg.printPropertyHeader("interfaces");
cg.printExpressionVector(m_base);
}
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
if (!m_docComment.empty()) {
cg.printPropertyHeader("comments");
cg.printValue(m_docComment);
}
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-13
Ver Arquivo
@@ -279,19 +279,6 @@ void ClassVariable::inferTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void ClassVariable::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ClassVariableStatement", 3);
cg.printPropertyHeader("modifiers");
m_modifiers->outputCodeModel(cg);
cg.printPropertyHeader("expressions");
cg.printExpressionVector(m_declaration);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-15
Ver Arquivo
@@ -90,21 +90,6 @@ void DoStatement::inferTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void DoStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("DoStatement", m_stmt != nullptr ? 3 : 2);
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("condition");
m_condition->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-11
Ver Arquivo
@@ -81,17 +81,6 @@ void EchoStatement::inferTypes(AnalysisResultPtr ar) {
m_exp->inferAndCheck(ar, Type::String, false);
}
///////////////////////////////////////////////////////////////////////////////
void EchoStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("EchoStatement", 2);
cg.printPropertyHeader("expression");
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-11
Ver Arquivo
@@ -96,17 +96,6 @@ void ExpStatement::inferTypes(AnalysisResultPtr ar) {
m_exp->inferAndCheck(ar, Type::Any, false);
}
///////////////////////////////////////////////////////////////////////////////
void ExpStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ExpressionStatement", 2);
cg.printPropertyHeader("expression");
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -92,19 +92,6 @@ void FinallyStatement::inferTypes(AnalysisResultPtr ar) {
if (m_stmt) m_stmt->inferTypes(ar);
}
///////////////////////////////////////////////////////////////////////////////
void FinallyStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("FinallyStatement", m_stmt == nullptr ? 1 : 2);
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-30
Ver Arquivo
@@ -120,36 +120,6 @@ void ForStatement::inferTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void ForStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 1;
if (m_exp1 != nullptr) numProps++;
if (m_exp2 != nullptr) numProps++;
if (m_exp3 != nullptr) numProps++;
if (m_stmt != nullptr) numProps++;
cg.printObjectHeader("ForStatement", numProps);
if (m_exp1 != nullptr) {
cg.printPropertyHeader("expression1");
m_exp1->outputCodeModel(cg);
}
if (m_exp2 != nullptr) {
cg.printPropertyHeader("expression2");
m_exp2->outputCodeModel(cg);
}
if (m_exp3 != nullptr) {
cg.printPropertyHeader("expression3");
m_exp3->outputCodeModel(cg);
}
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -151,30 +151,6 @@ void ForEachStatement::inferTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void ForEachStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 3;
if (m_name != nullptr) numProps++;
if (m_stmt != nullptr) numProps++;
cg.printObjectHeader("ForeachStatement", numProps);
cg.printPropertyHeader("collection");
m_array->outputCodeModel(cg);
if (m_name != nullptr) {
cg.printPropertyHeader("key");
m_name->outputCodeModel(cg);
}
cg.printPropertyHeader("value");
cg.printExpression(m_value, m_ref);
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -132,12 +132,6 @@ void FunctionStatement::analyzeProgram(AnalysisResultPtr ar) {
void FunctionStatement::inferTypes(AnalysisResultPtr ar) {
}
///////////////////////////////////////////////////////////////////////////////
void FunctionStatement::outputCodeModel(CodeGenerator &cg) {
MethodStatement::outputCodeModel(cg);
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-11
Ver Arquivo
@@ -135,17 +135,6 @@ void GlobalStatement::inferTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void GlobalStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("GlobalStatement", 2);
cg.printPropertyHeader("expressions");
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-11
Ver Arquivo
@@ -86,17 +86,6 @@ void GotoStatement::setNthKid(int n, ConstructPtr cp) {
void GotoStatement::inferTypes(AnalysisResultPtr ar) {
}
///////////////////////////////////////////////////////////////////////////////
void GotoStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("GotoStatement", 2);
cg.printPropertyHeader("label");
cg.printValue(m_label);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -83,25 +83,6 @@ void IfBranchStatement::inferTypes(AnalysisResultPtr ar) {
if (m_stmt) m_stmt->inferTypes(ar);
}
///////////////////////////////////////////////////////////////////////////////
void IfBranchStatement::outputCodeModel(CodeGenerator &cg) {
if (m_condition == nullptr) {
if (m_stmt != nullptr) m_stmt->outputCodeModel(cg);
return;
}
cg.printObjectHeader("ConditionalStatement", 3);
cg.printPropertyHeader("condition");
m_condition->outputCodeModel(cg);
if (m_stmt != nullptr) {
cg.printPropertyHeader("trueBlock");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-35
Ver Arquivo
@@ -216,41 +216,6 @@ void IfStatement::inferTypes(AnalysisResultPtr ar) {
if (m_stmts) m_stmts->inferTypes(ar);
}
///////////////////////////////////////////////////////////////////////////////
void IfStatement::outputCodeModel(CodeGenerator &cg) {
for (int i = 0; i < m_stmts->getCount(); i++) {
IfBranchStatementPtr branch =
dynamic_pointer_cast<IfBranchStatement>((*m_stmts)[i]);
assert(branch != nullptr); // this cast always succeeds, by construction.
auto condition = branch->getCondition();
auto statements = branch->getStmt();
auto numProps = 1;
if (condition != nullptr) numProps++;
if (statements != nullptr) numProps++;
if (i < m_stmts->getCount() - 1) numProps++;
if (i > 0) {
cg.printPropertyHeader("falseBlock");
if (i < m_stmts->getCount() - 1) {
printf("V:6:\"Vector\":1:{");
}
}
if (condition != nullptr) {
cg.printObjectHeader("ConditionalStatement", 3);
cg.printPropertyHeader("condition");
condition->outputCodeModel(cg);
cg.printPropertyHeader("trueBlock");
}
if (statements != nullptr) {
cg.printAsBlock(statements);
}
}
for (int i = 0; i < m_stmts->getCount() - 1; i++) {
cg.printf("}");
cg.printObjectFooter();
}
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -26,7 +26,6 @@
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/util/util.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/code_model_enums.h"
#include "hphp/compiler/parser/parser.h"
using namespace HPHP;
@@ -253,42 +252,6 @@ StatementPtr InterfaceStatement::preOptimize(AnalysisResultConstPtr ar) {
void InterfaceStatement::inferTypes(AnalysisResultPtr ar) {
}
///////////////////////////////////////////////////////////////////////////////
void InterfaceStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 3;
if (m_attrList != nullptr) numProps++;
if (m_base != nullptr) numProps++;
if (m_stmt != nullptr) numProps++;
if (!m_docComment.empty()) numProps++;
cg.printObjectHeader("TypeStatement", numProps);
if (m_attrList != nullptr) {
cg.printPropertyHeader("attributes");
cg.printExpressionVector(m_attrList);
}
cg.printPropertyHeader("kind");
cg.printValue(PHP_INTERFACE);
cg.printPropertyHeader("name");
cg.printValue(m_originalName);
//TODO: type parameters (task 3262469)
if (m_base != nullptr) {
cg.printPropertyHeader("interfaces");
cg.printExpressionVector(m_base);
}
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
if (!m_docComment.empty()) {
cg.printPropertyHeader("comments");
cg.printValue(m_docComment);
}
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-11
Ver Arquivo
@@ -67,17 +67,6 @@ void LabelStatement::setNthKid(int n, ConstructPtr cp) {
void LabelStatement::inferTypes(AnalysisResultPtr ar) {
}
///////////////////////////////////////////////////////////////////////////////
void LabelStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("LabelStatement", 2);
cg.printPropertyHeader("label");
cg.printValue(m_label);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
+1 -47
Ver Arquivo
@@ -547,8 +547,7 @@ void MethodStatement::inferFunctionTypes(AnalysisResultPtr ar) {
Variant(Variant::NullInit()));
ReturnStatementPtr returnStmt =
ReturnStatementPtr(
new ReturnStatement(getScope(), getLabelScope(),
getLocation(), constant));
new ReturnStatement(getScope(), getLocation(), constant));
m_stmt->addElement(returnStmt);
}
}
@@ -563,51 +562,6 @@ void MethodStatement::inferFunctionTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void MethodStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 3;
if (m_attrList != nullptr) numProps++;
if (m_ref) numProps++;
if (m_params != nullptr) numProps++;
if (m_retTypeAnnotation != nullptr) numProps++;
if (m_stmt != nullptr) numProps++;
if (!m_docComment.empty()) numProps++;
cg.printObjectHeader("FunctionStatement", numProps);
if (m_attrList != nullptr) {
cg.printPropertyHeader("attributes");
cg.printExpressionVector(m_attrList);
}
cg.printPropertyHeader("modifiers");
m_modifiers->outputCodeModel(cg);
if (m_ref) {
cg.printPropertyHeader("returnsReference");
cg.printValue(m_ref);
}
cg.printPropertyHeader("name");
cg.printValue(m_originalName);
//TODO: type parameters (task 3262469)
if (m_params != nullptr) {
cg.printPropertyHeader("parameters");
cg.printExpressionVector(m_params);
}
if (m_retTypeAnnotation != nullptr) {
cg.printPropertyHeader("returnType");
m_retTypeAnnotation->outputCodeModel(cg);
}
if (m_stmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_stmt);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
if (!m_docComment.empty()) {
cg.printPropertyHeader("comments");
cg.printValue(m_docComment);
}
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-14
Ver Arquivo
@@ -115,20 +115,6 @@ void ReturnStatement::inferTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void ReturnStatement::outputCodeModel(CodeGenerator &cg) {
auto nump = m_exp ? 2 : 1;
cg.printObjectHeader("ReturnStatement", nump);
if (m_exp) {
cg.printPropertyHeader("expression");
m_exp->outputCodeModel(cg);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
+1 -4
Ver Arquivo
@@ -28,10 +28,7 @@ const char *Statement::Names[] = {
};
Statement::Statement(STATEMENT_CONSTRUCTOR_BASE_PARAMETERS)
: Construct(scope, loc),
m_kindOf(kindOf),
m_labelScope(labelScope) {
DCHECK(m_labelScope != nullptr);
: Construct(scope, loc), m_kindOf(kindOf) {
}
///////////////////////////////////////////////////////////////////////////////
+5 -16
Ver Arquivo
@@ -18,23 +18,19 @@
#define incl_HPHP_STATEMENT_H_
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/analysis/label_scope.h"
#include <string>
#define STATEMENT_CONSTRUCTOR_BASE_PARAMETERS \
BlockScopePtr scope, LabelScopePtr labelScope, LocationPtr loc, \
Statement::KindOf kindOf
BlockScopePtr scope, LocationPtr loc, Statement::KindOf kindOf
#define STATEMENT_CONSTRUCTOR_BASE_PARAMETER_VALUES \
scope, labelScope, loc, kindOf
scope, loc, kindOf
#define STATEMENT_CONSTRUCTOR_PARAMETERS \
BlockScopePtr scope, LabelScopePtr labelScope, LocationPtr loc
BlockScopePtr scope, LocationPtr loc
#define STATEMENT_CONSTRUCTOR_PARAMETER_VALUES(kindOf) \
scope, labelScope, loc, Statement::KindOf##kindOf
scope, loc, Statement::KindOf##kindOf
#define DECLARE_BASE_STATEMENT_VIRTUAL_FUNCTIONS \
virtual void analyzeProgram(AnalysisResultPtr ar); \
virtual StatementPtr clone(); \
virtual void inferTypes(AnalysisResultPtr ar); \
virtual void outputCodeModel(CodeGenerator &cg); \
virtual void outputPHP(CodeGenerator &cg, AnalysisResultPtr ar);
#define DECLARE_STATEMENT_VIRTUAL_FUNCTIONS \
DECLARE_BASE_STATEMENT_VIRTUAL_FUNCTIONS; \
@@ -42,15 +38,12 @@
virtual int getKidCount() const; \
virtual void setNthKid(int n, ConstructPtr cp)
#define NULL_STATEMENT() \
BlockStatementPtr(new BlockStatement(getScope(), \
getLabelScope(), \
getLocation(), \
BlockStatementPtr(new BlockStatement(getScope(), getLocation(), \
StatementListPtr()))
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
DECLARE_BOOST_TYPES(Statement);
DECLARE_BOOST_TYPES(LabelScope);
#define DECLARE_STATEMENT_TYPES(x) \
x(FunctionStatement), \
@@ -156,14 +149,10 @@ public:
virtual int getRecursiveCount() const { return 1; }
LabelScopePtr getLabelScope() { return m_labelScope; }
void setLabelScope(LabelScopePtr labelScope) { m_labelScope = labelScope; }
protected:
KindOf m_kindOf;
int m_silencerCountMax;
int m_silencerCountCurrent;
LabelScopePtr m_labelScope;
};
///////////////////////////////////////////////////////////////////////////////
+1 -10
Ver Arquivo
@@ -262,8 +262,7 @@ bool StatementList::mergeConcatAssign() {
var, exp1, T_CONCAT_EQUAL));
}
expStmt = ExpStatementPtr
(new ExpStatement(getScope(), getLabelScope(),
getLocation(), exp));
(new ExpStatement(getScope(), getLocation(), exp));
m_stmts[i - length] = expStmt;
for (j = i - (length - 1); i > j; i--) removeElement(j);
@@ -414,14 +413,6 @@ void StatementList::inferTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void StatementList::outputCodeModel(CodeGenerator &cg) {
for (unsigned int i = 0; i < m_stmts.size(); i++) {
m_stmts[i]->outputCodeModel(cg);
}
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-11
Ver Arquivo
@@ -188,17 +188,6 @@ void StaticStatement::inferTypes(AnalysisResultPtr ar) {
scope->getVariables()->clearAttribute(VariableTable::InsideStaticStatement);
}
///////////////////////////////////////////////////////////////////////////////
void StaticStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("StaticStatement", 2);
cg.printPropertyHeader("expressions");
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-18
Ver Arquivo
@@ -185,24 +185,6 @@ void SwitchStatement::inferTypes(AnalysisResultPtr ar) {
}
}
///////////////////////////////////////////////////////////////////////////////
void SwitchStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 2;
if (m_cases != nullptr) numProps++;
cg.printObjectHeader("SwitchStatement", numProps);
cg.printPropertyHeader("expression");
m_exp->outputCodeModel(cg);
if (m_cases != nullptr) {
cg.printPropertyHeader("caseStatements");
cg.printStatementVector(m_cases);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-11
Ver Arquivo
@@ -73,17 +73,6 @@ void ThrowStatement::inferTypes(AnalysisResultPtr ar) {
m_exp->inferAndCheck(ar, Type::Object, false);
}
///////////////////////////////////////////////////////////////////////////////
void ThrowStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("ThrowStatement", 2);
cg.printPropertyHeader("expression");
m_exp->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -103,28 +103,6 @@ void TraitAliasStatement::setNthKid(int n, ConstructPtr cp) {
void TraitAliasStatement::inferTypes(AnalysisResultPtr ar) {
}
///////////////////////////////////////////////////////////////////////////////
void TraitAliasStatement::outputCodeModel(CodeGenerator &cg) {
auto propCount = 3;
auto traitName = m_traitName->getString();
if (!traitName.empty()) propCount++;
cg.printObjectHeader("TraitAliasStatement", propCount);
if (!traitName.empty()) {
cg.printPropertyHeader("traitName");
cg.printValue(traitName);
}
cg.printPropertyHeader("methodName1");
m_methodName->outputCodeModel(cg);
cg.printPropertyHeader("modifiers");
m_modifiers->outputCodeModel(cg);
cg.printPropertyHeader("methodName2");
m_newMethodName->outputCodeModel(cg);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
@@ -107,21 +107,6 @@ void TraitPrecStatement::setNthKid(int n, ConstructPtr cp) {
void TraitPrecStatement::inferTypes(AnalysisResultPtr ar) {
}
///////////////////////////////////////////////////////////////////////////////
void TraitPrecStatement::outputCodeModel(CodeGenerator &cg) {
cg.printObjectHeader("TraitInsteadStatement", 3);
cg.printPropertyHeader("traitName");
m_traitName->outputCodeModel(cg);
cg.printPropertyHeader("methodName");
m_methodName->outputCodeModel(cg);
cg.printPropertyHeader("otherTraitNames");
cg.printExpressionVector(m_otherTraitNames);
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
-25
Ver Arquivo
@@ -126,31 +126,6 @@ void TryStatement::inferTypes(AnalysisResultPtr ar) {
if (m_finallyStmt) m_finallyStmt->inferTypes(ar);
}
///////////////////////////////////////////////////////////////////////////////
void TryStatement::outputCodeModel(CodeGenerator &cg) {
auto numProps = 1;
if (m_tryStmt != nullptr) numProps++;
if (m_catches->getCount() > 0) numProps++;
if (m_finallyStmt != nullptr) numProps++;
cg.printObjectHeader("TryStatement", numProps);
if (m_tryStmt != nullptr) {
cg.printPropertyHeader("block");
cg.printAsBlock(m_tryStmt);
}
if (m_catches->getCount() > 0) {
cg.printPropertyHeader("catchStatements");
cg.printStatementVector(m_catches);
}
if (m_finallyStmt != nullptr) {
cg.printPropertyHeader("finallyStatement");
m_finallyStmt->outputCodeModel(cg);
}
cg.printPropertyHeader("location");
cg.printLocation(this->getLocation());
cg.printObjectFooter();
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais