49 Commits

Autor SHA1 Mensagem Data
Sara Golemon a3803ffa8a HPHP-2.0.2 2013-04-23 10:29:42 -07:00
Jordan DeLong a85369c7ce Fix some mismatched include guards 2013-04-22 23:34:10 -07:00
Edwin Smith 1cea03f3f7 hphp/src is now hphp/hphp
That's it
2013-04-22 23:32:31 -07:00
Mark Williams 52db7956bb Fix reflection for default values that were optimized
If a default value is optimized from a class constant,
to the value of the class constant, then reflection needs to
be able to get the text of the original class constant.
Fortunately hphp tags that onto the replacement expression for
just this reason. Lets use it in the emitter.
2013-04-22 23:31:09 -07:00
Mark Williams f6f1655ca5 Fix a crash if an exception is thrown in a constructor's surprise check
The unwinder assumed that if the actrec's constructor flag
was set, then there must be a $this. But the $this is cleared during
the return sequence.
2013-04-22 23:30:52 -07:00
Mark Williams 3fa077dd6f Free the VarEnv the correct way
detach, rather than destroy.
2013-04-22 23:30:12 -07:00
mwilliams 4caa51283a Fix order of evaluation for unused binary operators
eg

  (new X) == (new X);

Was converted to something like:

  (new X);
  (new X);

Which calls the destructor for the first X before constructing the second.

I tried a fix where we used an ExpressionList with ListKindLeft, which
would preserve both expressions until after both objects are created;
but that ends up calling the second object's destructor first. Thats
much better; its not clear to me that there's any guarantee about which
object's destructor is called first when they both go out of scope at
the same point; but currently hhvm and zend seem to aggree, so Im
going with a solution that preserves the left-to-right order.
2013-04-22 23:29:21 -07:00
aravind 4f70af91f7 Fix bug in shuffleArgs
This diff fixes a bug in shuffleArgs when there
are three register arguments in a cycle, and one
of them needs a zero extend.

Assume the shuffle that needs to be performed is
rdi -> rsi, rsi -> rdx, rdx -> rdi. doRegMoves()
determines the sequence of moves to be:

  xchg rdx, rsi
  xchg rsi, rdi

Assume also that the second dest reg (rsi) needs a zero extend.
The current implementatin will spit out the code
sequence:

  xchg   %rdx, %rsi
  movzbl %sil, %esi
  xchg   %rsi, %rdi
  movzbl %sil, $esi

Basically, the problem is that if a move sequence uses
two xchg's for a cycle of three registers, we should not perform
the zero extending (and address-lea) till both the exchanges are done.
2013-04-22 23:29:10 -07:00
mwilliams 8a0dd4fae4 Don't fold invalid string operations at compile time
It turns out the String::rvalAt and String::set don't raise
warnings on invalid offsets, so check explicitly before using them.
2013-04-22 23:10:28 -07:00
mwilliams afd5f72964 Fix crash in linting
Redeclared functions in non-whole-program analyze mode caused
an assertion failure.

Test Plan:
  % cat bug.php
  <?php
  if (isset($g)) {
    function f($x, $y) {}
  } else {
    function f($x) {}
  }
  f($x);
  % hphp -vWholeProgram=false -t analyze bug.php
2013-04-22 23:10:28 -07:00
mikemag ec6617f6bd Fix bug in heredoc processing
My recent change to now/heredoc processing resulted in variables in heredocs mistakenly being tacked onto the end of the previous line in the output. This tends not to be a problem when emitting things that get parsed by something else, like emitting PHP. But it's noticable when emitting raw text.
2013-04-22 23:10:28 -07:00
jdelong 964de35b10 Fix an exception safety issue for undefined properties in vectortranslator
I think the only case where we currently don't spillstack as
part of a vector translation is CGetM of a defined property.  However,
this can still raise exceptions in the unlikely case of an unset
property.  For now, just spill before any vector translation---a
follow up diff relaxes this to not do it in cases where we know the
property can't be undefined.  Presumably later we'll push the
spillstacks into the unlikely paths for these translations (or put
them in unwind handlers)---currently we can't handle control flow
where the join point has a different stack.
2013-04-22 23:10:27 -07:00
mwilliams 819058d081 Fix UnsetM with global base
If the global was not defined, it would try to return
a pointer into the MInstrCtx, which was not passed in.

We dont actually need it though, because in that case we can
just return a pointer to init_null_variant.
2013-04-22 23:10:27 -07:00
ptarjan e6542d070a stop segfaulting in propery_exists 2013-04-22 22:25:54 -07:00
mwilliams 83bd8ff445 Fix cgJcc for bool comparisons with constants
The bool value is in the bottom byte of the register,
with the rest of the register undefined, but we were doing
a 32 bit compare.
2013-04-22 21:55:22 -07:00
jdelong cf10678119 SpillStack of an ActRec is a use of the old fp
A bug like this was bound to happen.  Thanks to whoever added
the assert for saving me from real debugging (@smith?).
2013-04-22 18:19:58 -07:00
mwilliams 5226f80d05 Fix FPushClsMethodD in hhir
Non-persistent classes can't be burnt in (or at least,
you have to check the target cache before using it).
2013-04-22 18:19:45 -07:00
jdelong a2ffdae2cf Fix an assertion in traceRet, relating to generator frames
This was firing in my sandbox.  I didn't find anything that
looked like it changed it recently, so I'm not sure why it wasn't
firing earlier.
2013-04-22 18:18:59 -07:00
mikemag 785cf27e00 Fix heredoc/nowdoc bugs with large docs, docs crossing buffer boundaries
Fixed a few issues in the lexer for heredocs and nowdocs. The source file is read in 64k chunks, and any time a doc was split across a buffer boundary the lexer would fail to consume the doc properly. Modified the lexer to refill the file buffer when it is used, or when more data is needed in a variety of cases. Also fixed a number of other corner cases where we'd fail to recognize the doc end label or other special characters. The old code was also a bit over- and under-flowy.
2013-04-22 18:17:18 -07:00
bsimmers b32b2ec879 Fix baseValChanged check for empty base promotion in VectorEffects
I thought I'd have to teach memelim about the PtrToBoxed*
srcs for vector instructions but it turns out the refactoring I did in
the UnsetElem diff was enough. It already clears out the local map for
instructions that may modify refs.
2013-04-22 17:28:03 -07:00
mwilliams 1f638e631c Fix a crash in exif processing
Given a zero length string, the pointer was left unset, but
later code checked if the value of the pointer was non-null,
and ignored the length.
2013-04-22 17:27:47 -07:00
mwilliams 1ab14f87af Fix closure dispatch when there's more than one Func*
We need to make sure that we execute the code
corresponding to the actual Func*. This re-uses the
prolog array to hold the entry points for the cloned
Func*.
2013-04-22 17:27:32 -07:00
mwilliams fefd56e9d7 Fix refcounting issues with string SetM
The code was assuming that the result of the assignment
would be the value assigned, but its actually a new string
containing the first character of the value assigned. The result
was that the SetM had already decRef'd the rhs, and then the
jitted code decRef'd it again. Since that last decRef was a decRefNZ,
we would often get away with simply leaking both the original rhs and
the value of the SetM. But the new testcase crashes in a DEBUG build
without the fix.
2013-04-22 17:27:16 -07:00
mwilliams 17049b3a42 Fix assert in CodeGenerator::emitTypeCheck
The vector translator produced a type that was
boxed-array-or-string, which we couldnt guard on.

Since applying a SetM to a string will almost always produce
a string, change it to report string instead (which will still
be guarded on).
2013-04-22 17:25:04 -07:00
Sara Golemon be4c7698eb Switch to reentrant safe calls in posix
posix_getpwuid()
posix_getpwnam()
posix_getgrgid()
posix_getgrnam()
posix_ttyname()

were using non-threadsafe posix calls.
Most using AttachLiteral for shared space as well.
2013-03-28 12:47:16 -07:00
Sara Golemon 0dcbc83f74 Cast result of unpack to uint64_t when requesting unsigned type 'I'
ZendPack::unpack() always returns a signed int32_t,
regardless of actual storage type being unpacked.  For 32bit
unsigned types ('L', 'N', 'V', and 'I'(on I32 systems)) this
means overflowing in the helper and we have to explicitly
recast it to a uint64_t to get the data back out.

For LNV, this was already handled, it was missed for I.
2013-03-27 18:04:52 -07:00
Sara Golemon d660972153 HPHP 2.0.1 2013-03-22 19:14:35 -07:00
ptarjan ca437add64 fix this callsite incase someone ever does the TODO for setting valueClass() 2013-03-25 13:59:21 -07:00
mwilliams 3611bf3d58 Fix getContextClassName and getParentContextClassName
They both returned the late static bound class, not the context
class. This meant that eg "constant('self::FOO')" was actually
returning what "constant('static::FOO')" should have done.

In addition, we often want the Class*, not its name, so
change them to return Class*. The remaining places that then
read the name from the Class* should be fixed to use the Class*
directly (in a later diff).

Finally, noticed that while "defined()" was recently fixed to
support "static::", "constant()" was not. Pulled out a common
function to find the correct Class*.
2013-03-25 13:59:02 -07:00
jan 565c8477f8 Fix ref generator parameters
Alias manager does not know whether generator parameters are passed by
reference. This didn't matter, because every generator had at least one
function call (hphp_continuation_done()) that pretty much disabled unused
variable elimination.

This diff fixes that, lets us get rid of artificial function calls in
generators and will allow later improvements in alias manager.
2013-03-22 13:57:25 -07:00
mwilliams 8f3512f6d3 Filter strict_warnings like notices
There is a runtime option to filter out notices and warnings,
but strict_warnings were left out. Bundle them with notices.

We raise a lot of strict_warnings; and when we fix hphpiCompat
(to match zend better) we will raise a lot more, so this could
matter.
2013-03-22 13:57:18 -07:00
ottoni 7241c247dd Disable spilling into MMX registers 2013-03-22 13:57:06 -07:00
jan f06575d4e2 Fix local propagation of generator parameters
Alias manager does not know that generator parameters are populated and
assumes they are uninit. The current code works because control flow
algorithm gives up while trying to deal with the continuation switch
statement full of gotos.

This diff fixes it by setting isGeneratorParameter flag in symbols
representing parameters of enclosing generator wrapper and use variables
of enclosing closure.
2013-03-21 20:41:02 -07:00
Owen Yamauchi cc897749f8 Fix the RIP_REGISTER macro
Pretty simple. This makes me slightly nervous because I've only
confirmed it works in my stupid OpenEmbedded ARM SDK; a different Linux
might call this something else. But we'll cross that bridge when we get
to it, and this works for now.

I'm also sneaking in a change to remove x29 from the list of
callee-saved regs; I put it in there by accident last time.
2013-03-21 20:41:02 -07:00
ptarjan b597e3a753 fix static closures
I added the check for this in the interpreter but ##f_array_map## re-enteres the VM via a different path than FCall. Here is the equivilent check for the VM.
2013-03-21 20:41:02 -07:00
mwilliams 8ec621676d Fix args for embedded repo
When we generate a binary with an embedded repo,
we add various args (-vRepo.Authoritative etc) to the end
of the command line. But the argument "--" is taken to mean
"pass the rest of the args to the script". So if you use
"--" on such a binary, it gets rather badly broken.

Reorder the args so that the inserted ones come first.
2013-03-21 20:41:02 -07:00
mwilliams a134b25671 Fix nemo warnings about undefined $this
The fix for the crash caused us to take a different path
when checking locals.
2013-03-21 20:41:01 -07:00
mwilliams 15fa1ebfde Fix StringBuffer::resize()
capacity doesnt include the terminating null, so len is
allowed to grow to capacity (not capacity - 1).
2013-03-19 14:47:25 -07:00
mwilliams ce75713972 Fix assertion when target==analyze
Option::OutputHHBC should always be true.
2013-03-19 14:47:15 -07:00
Owen Yamauchi adc56c6d8c Fix includes in curl_tls_workarounds.cpp
raise_notice() wasn't declared in this file, so include runtime_error.h.
This caused further problems with ATTRIBUTE_PRINTF not being defined
yet, so include some more stuff.
2013-03-19 14:47:06 -07:00
Sara Golemon 3fb0fe8a6a SSL_OP_NO_TLSv1_2 is not supported by all openssl versions 2013-03-18 18:38:47 -07:00
ottoni 38306b527f SIMPLIFY_COMMUTATIVE only handles Type::Int
So check that the inputs are really Ints.
2013-03-18 18:38:37 -07:00
aravind e4e3bee5d3 Don't simplify Same to Eq to arrays 2013-03-18 18:38:29 -07:00
michalburger1 d25adc550b Fix bzdecompress
Bad memory allocation, the buffer needs to be large enough to fit all
the data we've decompressed so far plus the extra storage we're
incrementally allocationg, not just the incremental part.
2013-03-18 16:20:44 -07:00
Sara Golemon 8b23419a37 HPHP version 2.0.0 2013-03-14 16:00:42 -07:00
ottoni af5623b4fc Properly patch exit traces ending with JmpZero and JmpNZero
The hoistConditionalJumps pass was not handling traces ending with
JmpZero and JmpNZero.  This was resulting in spurious jumps to
'astubs' instead of patching the jcc+jump pair in 'a'.
2013-03-14 15:45:51 -07:00
ptarjan b51003b5aa tell closures about scope clones
In HHBC mode, traits are flattened into their classes.
When that happens, closures need to know about all the
classes that contain them so that when we find a ##$this##
inside the closure, it can tell EVERY containing scope to
please propogate ##$this## down to me.
2013-03-14 15:45:40 -07:00
mwilliams 5f019f5b43 Fix CodeGenerator::cgNInstanceOf
It assumed the result would be in rax, but it isnt always.
Use the correct register.
2013-03-13 10:16:23 -07:00
bertrand 35e347efa5 Fixed ContNext by writing InitNull rather than Uninit.
Apparently, m_received needs to be InitNull, rather than
Uninit.
2013-03-13 10:16:14 -07:00
30495 arquivos alterados com 835496 adições e 1706950 exclusões
+4 -16
Ver Arquivo
@@ -31,25 +31,14 @@ hphp.log
/hphp/runtime/tmp/run
/hphp/runtime/tmp/run.sh
/hphp/runtime/tmp/libtest.so
/hphp/hphp-build-info.cpp
/hphp/hphp-repo-schema.h
/hphp/runtime/vm/repo_schema.h
/hphp/hphpi/gen
/hphp/hphpi/hphpi
/hphp/hhvm/gen
/hphp/hhvm/hhvm
/hphp/runtime/ext/*.ext_hhvm.cpp
/hphp/runtime/ext/*.ext_hhvm.h
/hphp/runtime/ext/*/*.ext_hhvm.cpp
/hphp/runtime/ext/*/*.ext_hhvm.h
/hphp/runtime/ext_zend_compat/*/*.ext_hhvm.cpp
/hphp/runtime/ext_zend_compat/*/*.ext_hhvm.h
/hphp/runtime/ext_zend_compat/*/*/*.ext_hhvm.cpp
/hphp/runtime/ext_zend_compat/*/*/*.ext_hhvm.h
/hphp/runtime/base/builtin-functions.cpp.ext_hhvm.cpp
/hphp/runtime/base/builtin-functions.cpp.ext_hhvm.h
/hphp/runtime/ext_hhvm/ext_hhvm_infotabs.cpp
/hphp/runtime/ext_hhvm/ext_hhvm_infotabs.h
/hphp/tools/shmw/shmw
/hphp/ffi/java/classes
@@ -62,7 +51,6 @@ hphp.log
CMakeFiles
CMakeCache.txt
cmake_install.cmake
install_manifest.txt
/output_gd/
-26
Ver Arquivo
@@ -1,26 +0,0 @@
language: cpp
compiler:
- gcc
before_script:
- TRAVIS=1 ./configure_ubuntu_12.04.sh
# for some tests
- sudo locale-gen de_DE && sudo locale-gen zh_CN.utf8 && sudo locale-gen fr_FR
- HPHP_HOME=`pwd` make -j 6
# Test suites take longer to run in RepoAuthoritative mode (-r) than normal so
# split out the -r from normal runs and further split the -r runs by suite to
# avoid the possibility of slower machines exceeding the 50 minute test timeout
env:
- TEST_RUN_MODE="-m jit all"
- TEST_RUN_MODE="-m interp all"
- TEST_RUN_MODE="-m jit -r quick slow"
- TEST_RUN_MODE="-m interp -r quick slow"
- TEST_RUN_MODE="-m jit -r zend"
- TEST_RUN_MODE="-m interp -r zend"
script: hphp/hhvm/hhvm hphp/test/run $TEST_RUN_MODE
notifications:
irc: "chat.freenode.net#hhvm"
-13
Ver Arquivo
@@ -1,13 +0,0 @@
if (EDITLINE_LIBRARIES AND EDITLINE_INCLUDE_DIRS)
set (Editline_FIND_QUIETLY TRUE)
endif (EDITLINE_LIBRARIES AND EDITLINE_INCLUDE_DIRS)
find_path(EDITLINE_INCLUDE_DIRS NAMES editline/readline.h)
find_library(EDITLINE_LIBRARIES NAMES edit)
include (FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Editline DEFAULT_MSG
EDITLINE_LIBRARIES
EDITLINE_INCLUDE_DIRS)
mark_as_advanced(EDITLINE_INCLUDE_DIRS EDITLINE_LIBRARIES)
-14
Ver Arquivo
@@ -56,20 +56,6 @@ if(ICU_INCLUDE_DIR AND ICU_LIBRARY)
set(ICU_I18N_FOUND 0)
set(ICU_I18N_LIBRARIES)
endif (ICU_I18N_LIBRARY)
# Look for the ICU data libraries
find_library(
ICU_DATA_LIBRARY
NAMES icudata cygicudata cygicudata32
DOC "Libraries to link against for ICU data")
mark_as_advanced(ICU_DATA_LIBRARY)
if (ICU_DATA_LIBRARY)
set(ICU_DATA_FOUND 1)
set(ICU_DATA_LIBRARIES ${ICU_DATA_LIBRARY})
else (ICU_DATA_LIBRARY)
set(ICU_DATA_FOUND 0)
set(ICU_DATA_LIBRARIES)
endif (ICU_DATA_LIBRARY)
else(ICU_INCLUDE_DIR AND ICU_LIBRARY)
set(ICU_FOUND 0)
set(ICU_I18N_FOUND 0)
-27
Ver Arquivo
@@ -1,27 +0,0 @@
# - Try to find libdl
# Once done this will define
#
# LIBDL_FOUND - system has libdl
# LIBDL_INCLUDE_DIRS - the libdl include directory
# LIBDL_LIBRARIES - Link these to use libdl
# LIBDL_NEEDS_UNDERSCORE - If extern "C" symbols are prefixed (BSD/Apple)
#
find_path (LIBDL_INCLUDE_DIRS NAMES dlfcn.h)
find_library (LIBDL_LIBRARIES NAMES dl)
include (FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibDL DEFAULT_MSG
LIBDL_LIBRARIES
LIBDL_INCLUDE_DIRS)
SET(CMAKE_REQUIRED_LIBRARIES dl)
INCLUDE(CheckCSourceRuns)
CHECK_C_SOURCE_RUNS("#include <dlfcn.h>
void testfunc() {}
int main() {
testfunc();
return dyslm(0, \"_testfunc\") != (void*)0;
}" LIBDL_NEEDS_UNDERSCORE)
mark_as_advanced(LIBDL_INCLUDE_DIRS LIBDL_LIBRARIES LIBDL_NEEDS_UNDERSCORE)
+1 -10
Ver Arquivo
@@ -51,14 +51,5 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibElf DEFAULT_MSG
LIBELF_LIBRARIES
LIBELF_INCLUDE_DIRS)
SET(CMAKE_REQUIRED_LIBRARIES elf)
INCLUDE(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("#include <libelf.h>
int main() {
Elf *e = (Elf*)0;
size_t sz;
elf_getshdrstrndx(e, &sz);
return 0;
}" ELF_GETSHDRSTRNDX)
mark_as_advanced(LIBELF_INCLUDE_DIRS LIBELF_LIBRARIES ELF_GETSHDRSTRNDX)
mark_as_advanced(LIBELF_INCLUDE_DIRS LIBELF_LIBRARIES)
-13
Ver Arquivo
@@ -1,13 +0,0 @@
if (LIBNUMA_LIBRARIES AND LIBNUMA_INCLUDE_DIRS)
set (LibNuma_FIND_QUIETLY TRUE)
endif (LIBNUMA_LIBRARIES AND LIBNUMA_INCLUDE_DIRS)
find_path(LIBNUMA_INCLUDE_DIRS NAMES numa.h)
find_library(LIBNUMA_LIBRARIES NAMES numa)
include (FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibNuma DEFAULT_MSG
LIBNUMA_LIBRARIES
LIBNUMA_INCLUDE_DIRS)
mark_as_advanced(LIBNUMA_INCLUDE_DIRS LIBNUMA_LIBRARIES)
+28
Ver Arquivo
@@ -0,0 +1,28 @@
#
# $Id$
#
# - Find libunwind
# Find libunwind
#
# LIBUNWIND_INCLUDE_DIR - where to find unwind.h and libunwind.h
# LIBUNWIND_LIBRARY - List of libraries when using libunwind
# LIBUNWIND_FOUND - True if libunwind found.
if(LIBUNWIND_INCLUDE_DIR)
# Already in cache, be silent
SET(LIBUNWIND_FIND_QUIETLY TRUE)
endif()
FIND_PATH(LIBUNWIND_INCLUDE_DIR libunwind.h)
if(NOT EXISTS "${LIBUNWIND_INCLUDE_DIR}/unwind.h")
message(FATAL_ERROR "libunwind.h found without matching unwind.h")
SET(LIBUNWIND_INCLUDE_DIR "")
endif()
FIND_LIBRARY(LIBUNWIND_LIBRARY unwind)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUNWIND DEFAULT_MSG LIBUNWIND_LIBRARY LIBUNWIND_INCLUDE_DIR)
MARK_AS_ADVANCED(LIBUNWIND_LIBRARY LIBUNWIND_INCLUDE_DIR)
+1 -1
Ver Arquivo
@@ -29,7 +29,7 @@
#-------------- FIND MYSQL_INCLUDE_DIR ------------------
FIND_PATH(MYSQL_INCLUDE_DIR mysql.h
FIND_PATH(MYSQL_INCLUDE_DIR mysql/mysql.h
$ENV{MYSQL_INCLUDE_DIR}
$ENV{MYSQL_DIR}/include
/usr/include/mysql
-27
Ver Arquivo
@@ -1,27 +0,0 @@
# - Try to find libpthread
#
# Once done this will define
#
# LIBPTHREAD_FOUND - system has libpthread
# LIBPTHREAD_INCLUDE_DIRS - the libpthread include directory
# LIBPTHREAD_LIBRARIES - Link these to use libpthread
# LIBPTHREAD_DEFINITIONS - Compiler switches required for using libpthread
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
if (LIBPTHREAD_LIBRARIES AND LIBPTHREAD_INCLUDE_DIRS)
set (LIBPTHREAD_FIND_QUIETLY TRUE)
endif (LIBPTHREAD_LIBRARIES AND LIBPTHREAD_INCLUDE_DIRS)
find_path (LIBPTHREAD_INCLUDE_DIRS NAMES pthread.h)
find_library (LIBPTHREAD_LIBRARIES NAMES pthread)
include (FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBPTHREAD DEFAULT_MSG
LIBPTHREAD_LIBRARIES LIBPTHREAD_INCLUDE_DIRS)
mark_as_advanced(LIBPTHREAD_INCLUDE_DIRS LIBPTHREAD_LIBRARIES LIBPTHREAD_FOUND)
-61
Ver Arquivo
@@ -1,61 +0,0 @@
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
#error Not GCC 4.7.0+
#endif
int main() { return 0; }" HAVE_GCC_47)
CHECK_C_SOURCE_COMPILES("#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION < 40800
#error Not GCC 4.8.0+
#endif
int main() { return 0; }" HAVE_GCC_48)
endif()
set(FREEBSD FALSE)
set(LINUX FALSE)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
set(FREEBSD TRUE)
endif()
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(LINUX TRUE)
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-120 -Wall -Woverloaded-virtual -Wno-deprecated -w1 -Wno-strict-aliasing -Wno-write-strings -Wno-invalid-offsetof -fno-operator-names")
else()
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_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-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)
set(CMAKE_C_FLAGS_RELEASE "-O3")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
endif()
+53 -83
Ver Arquivo
@@ -17,17 +17,8 @@
include(CheckFunctionExists)
# libdl
find_package(LibDL)
if (LIBDL_INCLUDE_DIRS)
add_definitions("-DHAVE_LIBDL")
include_directories(${LIBDL_INCLUDE_DIRS})
if (LIBDL_NEEDS_UNDERSCORE)
add_definitions("-DLIBDL_NEEDS_UNDERSCORE")
endif()
endif()
# boost checks
find_package(Boost 1.48.0 COMPONENTS system program_options filesystem regex REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
@@ -48,6 +39,10 @@ if (LIBINOTIFY_INCLUDE_DIR)
include_directories(${LIBINOTIFY_INCLUDE_DIR})
endif()
# unwind checks
find_package(Libunwind REQUIRED)
include_directories(${LIBUNWIND_INCLUDE_DIR})
# iconv checks
find_package(Libiconv REQUIRED)
include_directories(${LIBICONV_INCLUDE_DIR})
@@ -97,6 +92,13 @@ set(CMAKE_REQUIRED_LIBRARIES)
# GD checks
find_package(GD REQUIRED)
if (WANT_FB_LIBMCC)
add_definitions(-DHPHP_WITH_LIBMCC)
message(FATAL_ERROR Need to add libmcc and libch for linking)
else ()
# nothing for now
endif()
find_package(LibXed)
if (LibXed_INCLUDE_DIR AND LibXed_LIBRARY)
include_directories(${LibXed_INCLUDE_DIR})
@@ -137,6 +139,16 @@ 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")
FIND_LIBRARY(XHP_LIB xhp)
FIND_PATH(XHP_INCLUDE_DIR xhp_preprocess.hpp)
if (XHP_LIB AND XHP_INCLUDE_DIR)
include_directories(${XHP_INCLUDE_DIR})
set(SKIP_BUNDLED_XHP ON)
else()
include_directories("${HPHP_HOME}/hphp/third_party/xhp/xhp")
endif()
# ICU
find_package(ICU REQUIRED)
if (ICU_FOUND)
@@ -149,6 +161,9 @@ if (ICU_FOUND)
include_directories(${ICU_INCLUDE_DIRS})
endif (ICU_FOUND)
# (google heap OR cpu profiler) AND libunwind
FIND_LIBRARY(UNWIND_LIB unwind)
# jemalloc/tmalloc and profiler
if (USE_GOOGLE_HEAP_PROFILER OR USE_GOOGLE_CPU_PROFILER)
FIND_LIBRARY(GOOGLE_PROFILER_LIB profiler)
@@ -173,35 +188,17 @@ if (USE_GOOGLE_HEAP_PROFILER AND GOOGLE_PROFILER_LIB)
endif()
endif()
if (USE_JEMALLOC AND NOT GOOGLE_TCMALLOC_ENABLED)
FIND_LIBRARY(JEMALLOC_LIB NAMES jemalloc)
FIND_PATH(JEMALLOC_INCLUDE_DIR NAMES jemalloc/jemalloc.h)
if (JEMALLOC_INCLUDE_DIR AND JEMALLOC_LIB)
include_directories(${JEMALLOC_INCLUDE_DIR})
set (CMAKE_REQUIRED_INCLUDES ${JEMALLOC_INCLUDE_DIR})
INCLUDE(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("
#include <jemalloc/jemalloc.h>
int main(void) {
#if !defined(JEMALLOC_VERSION_MAJOR) || (JEMALLOC_VERSION_MAJOR < 3)
# error \"jemalloc version >= 3.0.0 required\"
#endif
return 0;
}" JEMALLOC_VERSION_3)
set (CMAKE_REQUIRED_INCLUDES)
if (JEMALLOC_VERSION_3)
message(STATUS "Found jemalloc: ${JEMALLOC_LIB}")
set(JEMALLOC_ENABLED 1)
else()
message(STATUS "Found jemalloc, but it was too old")
endif()
if (USE_JEMALLOC AND NOT GOOGLE_TCMALLOC_ENABLED
AND NOT CMAKE_BUILD_TYPE STREQUAL Debug)
FIND_LIBRARY(JEMALLOC_LIB jemalloc)
if (JEMALLOC_LIB)
message(STATUS "Found jemalloc: ${JEMALLOC_LIB}")
set(JEMALLOC_ENABLED 1)
endif()
endif()
if (USE_TCMALLOC AND NOT JEMALLOC_ENABLED AND NOT GOOGLE_TCMALLOC_ENABLED)
if (USE_TCMALLOC AND NOT JEMALLOC_ENABLED AND NOT GOOGLE_TCMALLOC_ENABLED
AND NOT CMAKE_BUILD_TYPE STREQUAL Debug)
FIND_LIBRARY(GOOGLE_TCMALLOC_MIN_LIB tcmalloc_minimal)
if (GOOGLE_TCMALLOC_MIN_LIB)
message(STATUS "Found minimal tcmalloc: ${GOOGLE_TCMALLOC_MIN_LIB}")
@@ -268,21 +265,8 @@ include_directories(${LDAP_INCLUDE_DIR})
find_package(Ncurses REQUIRED)
include_directories(${NCURSES_INCLUDE_PATH})
# libpthreads
find_package(PThread REQUIRED)
include_directories(${LIBPTHREAD_INCLUDE_DIRS})
# Either Readline or Editline (for hphpd)
find_package(Readline)
find_package(Editline)
if (READLINE_INCLUDE_DIR)
include_directories(${READLINE_INCLUDE_DIR})
elseif (EDITLINE_INCLUDE_DIRS)
add_definitions("-DUSE_EDITLINE")
include_directories(${EDITLINE_INCLUDE_DIRS})
else()
message(FATAL_ERROR "Could not find Readline or Editline")
endif()
find_package(Readline REQUIRED)
include_directories(${READLINE_INCLUDE_DIR})
find_package(CClient REQUIRED)
include_directories(${CCLIENT_INCLUDE_PATH})
@@ -292,9 +276,6 @@ include_directories(${LIBDWARF_INCLUDE_DIRS})
find_package(LibElf REQUIRED)
include_directories(${LIBELF_INCLUDE_DIRS})
if (ELF_GETSHDRSTRNDX)
add_definitions("-DHAVE_ELF_GETSHDRSTRNDX")
endif()
CONTAINS_STRING("${CCLIENT_INCLUDE_PATH}/utf8.h" U8T_DECOMPOSE RECENT_CCLIENT)
if (NOT RECENT_CCLIENT)
@@ -319,9 +300,12 @@ if (NOT CCLIENT_HAS_SSL)
add_definitions(-DSKIP_IMAP_SSL=1)
endif()
FIND_LIBRARY(CRYPT_LIB NAMES xcrypt crypt crypto)
if (LINUX OR FREEBSD)
FIND_LIBRARY (CRYPT_LIB NAMES xcrypt crypt)
FIND_LIBRARY (RT_LIB rt)
elseif (APPLE)
FIND_LIBRARY (CRYPT_LIB crypto)
FIND_LIBRARY (ICONV_LIB iconv)
endif()
if (LINUX)
@@ -355,14 +339,6 @@ if (FREEBSD)
endif()
endif()
if (APPLE)
find_library(LIBINTL_LIBRARIES NAMES intl libintl)
if (LIBINTL_INCLUDE_DIR)
include_directories(${LIBINTL_INCLUDE_DIR})
endif()
find_library(KERBEROS_LIB NAMES gssapi_krb5)
endif()
#find_package(BISON REQUIRED)
#find_package(FLEX REQUIRED)
@@ -374,10 +350,6 @@ include_directories(${HPHP_HOME}/hphp)
include_directories(${HPHP_HOME}/hphp/system/gen)
macro(hphp_link target)
if (LIBDL_LIBRARIES)
target_link_libraries(${target} ${LIBDL_LIBRARIES})
endif ()
if (GOOGLE_HEAP_PROFILER_ENABLED OR GOOGLE_CPU_PROFILER_ENABLED)
target_link_libraries(${target} ${GOOGLE_PROFILER_LIB})
endif()
@@ -393,9 +365,10 @@ macro(hphp_link target)
endif()
target_link_libraries(${target} ${Boost_LIBRARIES})
target_link_libraries(${target} ${LIBUNWIND_LIBRARY})
target_link_libraries(${target} ${MYSQL_CLIENT_LIBS})
target_link_libraries(${target} ${PCRE_LIBRARY})
target_link_libraries(${target} ${ICU_DATA_LIBRARIES} ${ICU_I18N_LIBRARIES} ${ICU_LIBRARIES})
target_link_libraries(${target} ${ICU_LIBRARIES} ${ICU_I18N_LIBRARIES})
target_link_libraries(${target} ${LIBEVENT_LIB})
target_link_libraries(${target} ${CURL_LIBRARIES})
target_link_libraries(${target} ${LIBGLOG_LIBRARY})
@@ -426,16 +399,9 @@ if (FREEBSD)
target_link_libraries(${target} ${EXECINFO_LIB})
endif()
if (APPLE)
target_link_libraries(${target} ${LIBINTL_LIBRARIES})
target_link_libraries(${target} ${KERBEROS_LIB})
endif()
target_link_libraries(${target} ${BFD_LIB})
target_link_libraries(${target} ${BINUTIL_LIB})
if (${LIBPTHREAD_LIBRARIES})
target_link_libraries(${target} ${LIBPTHREAD_LIBRARIES})
endif()
target_link_libraries(${target} pthread)
target_link_libraries(${target} ${TBB_LIBRARIES})
target_link_libraries(${target} ${OPENSSL_LIBRARIES})
target_link_libraries(${target} ${ZLIB_LIBRARIES})
@@ -452,9 +418,12 @@ endif()
target_link_libraries(${target} ${LIBMEMCACHED_LIBRARY})
target_link_libraries(${target} ${CRYPT_LIB})
if (LINUX OR FREEBSD)
target_link_libraries(${target} ${CRYPT_LIB})
target_link_libraries(${target} ${RT_LIB})
elseif (APPLE)
target_link_libraries(${target} ${CRYPTO_LIB})
target_link_libraries(${target} ${ICONV_LIB})
endif()
target_link_libraries(${target} timelib)
@@ -463,15 +432,16 @@ endif()
target_link_libraries(${target} double-conversion)
target_link_libraries(${target} folly)
if (SKIP_BUNDLED_XHP)
target_link_libraries(${target} ${XHP_LIB})
else()
target_link_libraries(${target} xhp)
endif()
target_link_libraries(${target} afdt)
target_link_libraries(${target} mbfl)
if (READLINE_LIBRARY)
target_link_libraries(${target} ${READLINE_LIBRARY})
elseif (EDITLINE_LIBRARIES)
target_link_libraries(${target} ${EDITLINE_LIBRARIES})
endif()
target_link_libraries(${target} ${READLINE_LIBRARY})
target_link_libraries(${target} ${NCURSES_LIBRARY})
target_link_libraries(${target} ${CCLIENT_LIBRARY})
-43
Ver Arquivo
@@ -67,46 +67,3 @@ macro(MYSQL_SOCKET_SEARCH)
set(MYSQL_UNIX_SOCK_ADDR ${MYSQL_SOCK} CACHE STRING "Path to MySQL Socket")
endif()
endmacro()
function(embed_systemlib TARGET DEST SOURCE)
if (APPLE)
target_link_libraries(${TARGET} -Wl,-sectcreate,__text,systemlib,${SOURCE})
else()
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND "objcopy"
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)
# 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})
set_target_properties(${EXTNAME} PROPERTIES PREFIX "")
set_target_properties(${EXTNAME} PROPERTIES SUFFIX ".so")
endfunction()
function(HHVM_SYSTEMLIB EXTNAME SOURCE_FILE)
embed_systemlib(${EXTNAME} "${EXTNAME}.so" ${SOURCE_FILE})
endfunction()
+66 -46
Ver Arquivo
@@ -1,22 +1,5 @@
include(Options)
if (APPLE)
set(HHVM_ANCHOR_SYMS -Wl,-u,_register_libevent_server)
else()
set(HHVM_ANCHOR_SYMS -Wl,-uregister_libevent_server)
endif()
set(HHVM_LINK_LIBRARIES
hphp_analysis
hphp_runtime_static
ext_hhvm_static
hphp_system
hphp_parser
hphp_zend
hphp_util
vixl neo
${HHVM_ANCHOR_SYMS})
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
@@ -25,13 +8,29 @@ 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)
if(CMAKE_COMPILER_IS_GNUCC)
INCLUDE(CheckCSourceCompiles)
CHECK_C_SOURCE_COMPILES("#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if GCC_VERSION < 40400
#error Need GCC 4.4.0+
#endif
int main() { return 0; }" HAVE_GCC_44)
if(NOT HAVE_GCC_44)
message(FATAL_ERROR "Need at least GCC 4.4")
endif()
endif()
set(FREEBSD FALSE)
set(LINUX FALSE)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
set(FREEBSD TRUE)
endif()
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(LINUX TRUE)
endif()
LIST(APPEND CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}")
@@ -43,17 +42,12 @@ if(APPLE)
endif()
endif()
include(HPHPCompiler)
include(HPHPFunctions)
include(HPHPFindLibs)
add_definitions(-D_REENTRANT=1 -D_PTHREADS=1 -D__STDC_FORMAT_MACROS)
add_definitions(-D_GNU_SOURCE -D_REENTRANT=1 -D_PTHREADS=1)
add_definitions(-DHHVM_LIB_PATH_DEFAULT="${HPHP_HOME}/bin")
if (LINUX)
add_definitions(-D_GNU_SOURCE)
endif()
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
add_definitions(-DRELEASE=1)
add_definitions(-DNDEBUG)
@@ -63,6 +57,22 @@ else()
message("Generating DEBUG build")
endif()
if(INFINITE_LOOP_DETECTION)
add_definitions(-DINFINITE_LOOP_DETECTION=1)
endif()
if(INFINITE_RECURSION_DETECTION)
add_definitions(-DINFINITE_RECURSION_DETECTION=1)
endif()
if(REQUEST_TIMEOUT_DETECTION)
add_definitions(-DREQUEST_TIMEOUT_DETECTION=1)
endif()
if(ENABLE_LATE_STATIC_BINDING)
add_definitions(-DENABLE_LATE_STATIC_BINDING=1)
endif()
if(DEBUG_MEMORY_LEAK)
add_definitions(-DDEBUG_MEMORY_LEAK=1)
endif()
@@ -79,6 +89,10 @@ if(HOTPROFILER)
add_definitions(-DHOTPROFILER=1)
endif()
if(HOTPROFILER_NO_BUILTIN)
add_definitions(-DHOTPROFILER_NO_BUILTIN=1)
endif()
if(EXECUTION_PROFILER)
add_definitions(-DEXECUTION_PROFILER=1)
endif()
@@ -91,25 +105,31 @@ if(APPLE OR FREEBSD)
add_definitions(-DSKIP_USER_CHANGE=1)
endif()
if(APPLE)
# We have to be a little more permissive in some cases.
add_definitions(-fpermissive)
# Skip deprecation warnings in OpenSSL.
add_definitions(-DMAC_OS_X_VERSION_MIN_REQUIRED=MAC_OS_X_VERSION_10_6)
# Just assume we have sched.h
add_definitions(-DFOLLY_HAVE_SCHED_H=1)
# Enable weak linking
add_definitions(-DMACOSX_DEPLOYMENT_TARGET=10.6)
endif()
# enable the OSS options if we have any
add_definitions(-DHPHP_OSS=1)
# later versions of binutils don't play well without automake
add_definitions(-DPACKAGE=hhvm -DPACKAGE_VERSION=Release)
execute_process(COMMAND git describe --all --long --abbrev=40 --always
OUTPUT_VARIABLE _COMPILER_ID OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
if (_COMPILER_ID)
add_definitions(-DCOMPILER_ID="${_COMPILER_ID}")
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-120 -Wall -Woverloaded-virtual -Wno-deprecated -w1 -Wno-strict-aliasing -Wno-write-strings -Wno-invalid-offsetof -fno-operator-names")
else()
set(CMAKE_C_FLAGS "-w")
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")
endif()
IF(CMAKE_COMPILER_IS_GNUCC)
SET (CMAKE_C_FLAGS_RELEASE "-O3")
ENDIF()
IF(CMAKE_COMPILER_IS_GNUCXX)
SET (CMAKE_CXX_FLAGS_RELEASE "-O3")
ENDIF()
include_directories(${HPHP_HOME}/hphp)
include_directories(${HPHP_HOME}/hphp/lib/system/gen)
+9
Ver Arquivo
@@ -1,13 +1,22 @@
#set(CMAKE_BUILD_TYPE Debug)
option(ENABLE_LATE_STATIC_BINDING "Enable Late Static Binding" ON)
option(INFINITE_LOOP_DETECTION "Enable Infinite Loop Detection" ON)
option(INFINITE_RECURSION_DETECTION "Enable Infinite Recursion Detection" ON)
option(REQUEST_TIMEOUT_DETECTION "Enable Timeout Detection" ON)
option(ALWAYS_ASSERT "Enabled asserts in a release build" OFF)
option(DEBUG_MEMORY_LEAK "Allow easier debugging of memory leaks" OFF)
option(DEBUG_APC_LEAK "Allow easier debugging of apc leaks" OFF)
option(HOTPROFILER "Enable support for the hot-profiler" OFF)
option(HOTPROFILER_NO_BUILTIN "Don't consider builtins for the hot-profiler" OFF)
option(EXECUTION_PROFILER "Enable the execution profiler" OFF)
option(ENABLE_FULL_SETLINE "Enable full setline function for debugger and code-coverage" OFF)
option(WANT_FB_LIBMCC "want FB Memcache" OFF)
option(USE_JEMALLOC "Use jemalloc" ON)
option(USE_TCMALLOC "Use tcmalloc (if jemalloc is not used)" ON)
+2 -2
Ver Arquivo
@@ -1,5 +1,5 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.5 FATAL_ERROR)
PROJECT(hphp C CXX ASM)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.4 FATAL_ERROR)
PROJECT(hphp C CXX)
IF("$ENV{HPHP_HOME}" STREQUAL "")
message(FATAL_ERROR "You should set the HPHP_HOME environmental")
-18
Ver Arquivo
@@ -1,18 +0,0 @@
# Contributing to HipHop
We'd love to have your help in making HipHop better. 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.
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/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.
## Submitting Pull Requests
Before changes can be accepted a [Contributor Licensing 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.
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.
## Additional Resources
* IRC:[#hhvm on freenode](http://webchat.freenode.net/?channels=hhvm)
* [Issue tracker](http://github.com/facebook/hiphop-php/issues)
+58 -26
Ver Arquivo
@@ -1,46 +1,78 @@
# HipHop VM for PHP [![Build Status](https://travis-ci.org/facebook/hiphop-php.png?branch=master)](https://travis-ci.org/facebook/hiphop-php)
# HipHop for PHP
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.
HipHop is a high performance PHP toolchain. Currently supported platforms are Linux and FreeBSD. There is no OS X support.
HipHop is most commonly run as a standalone server, replacing both Apache and modphp.
* [Developer Mailing List](http://groups.google.com/group/hiphop-php-dev)
* [Wiki](http://wiki.github.com/facebook/hiphop-php)
* [Issue Tracker](http://github.com/facebook/hiphop-php/issues)
## FAQ
## Required Packages
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.
The latest information is available on the [wiki](http://wiki.github.com/facebook/hiphop-php/building-and-installing)
## Installing
* cmake *2.6 is the minimum version*
* g++/gcc *4.3 is the minimum version*
* Boost *1.37 is the minimum version*
* flex
* bison
* re2c
* libmysql
* libxml2
* libmcrypt
* libicu *4.2 is the minimum version*
* openssl
* binutils
* libcap
* gd
* zlib
* tbb *Intel's Thread Building Blocks*
* [Oniguruma](http://www.geocities.jp/kosako3/oniguruma/)
* libpcre
* libexpat
* libmemcached
* google-glog (http://code.google.com/p/google-glog/)
* libc-client2007
* libdwarf
* libelf
* libunwind
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).
The following packages have had slight modifications added to them. Patches are provided and should be made against the current source copies.
## Running
* [libcurl](http://curl.haxx.se/download.html)
* hphp/third_party/libcurl.fb-changes.diff
* [libevent 1.4](http://www.monkey.org/~provos/libevent/)
* hphp/third_party/libevent-1.4.14.fb-changes.diff
You can run standalone programs just by passing them to hhvm: `hhvm my_script.php`.
## Installation
HipHop bundles in a webserver. So if you want to run on port 80 in the current directory:
You may need to point CMake to the location of your custom libcurl and libevent, or to any other libraries which needed to be installed. The *CMAKE_PREFIX_PATH* variable is used to hint to the location.
```
sudo hhvm -m server
```
export CMAKE_PREFIX_PATH=/home/user
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`.
To build HipHop, use the following:
## Contributing
Linux:
We'd love to have your help in making HipHop better.
cd /home/user/dev
git clone git://github.com/facebook/hiphop-php.git
cd hiphop-php
git submodule init
git submodule update
export HPHP_HOME=`pwd`
export HPHP_LIB=`pwd`/bin
cmake .
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 are using FreeBSD instead use export - setenv
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).
Once this is done you can generate the build file. This will return you to the shell. Finally, to build, run `make`. If any errors occur, it may be required to remove the CMakeCache.txt directory in the checkout.
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.
make
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.
## Contributing to HipHop
HipHop is licensed under the PHP and Zend licenses except as otherwise noted.
Before changes can be accepted a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed and returned.
## License
## Running HipHop
HipHop VM is licensed under the PHP and Zend licenses except as otherwise noted.
## Reporting Crashes
See [Reporting Crashes](https://github.com/facebook/hiphop-php/wiki/Reporting-Crashes) for helpful tips on how to report crashes in an actionable manner.
Please see [the wiki page](http://wiki.github.com/facebook/hiphop-php/running-hiphop)
+5579
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
-104
Ver Arquivo
@@ -1,104 +0,0 @@
#########################################
#
# Install all the dependancies for HipHop
#
#########################################
SCRIPT_NAME='./configure_ubuntu_12.04.sh'
if [ "$0" != "$SCRIPT_NAME" ]; then
echo "Run the script from the hiphop-php directory like:"
echo " $SCRIPT_NAME"
exit 1
fi
if [ "x${TRAVIS}" != "x" ]; then
# Collect some stats for use in tuning build later on
free
CPUS=`cat /proc/cpuinfo | grep -E '^processor' | tail -1 | cut -d : -f 2`
CPUS=`expr ${CPUS} + 1`
echo "CPUs: ${CPUS}"
fi
export CMAKE_PREFIX_PATH=`/bin/pwd`/..
export HPHP_HOME=`/bin/pwd`
# install apt-fast to speedup later dependency installation
sudo add-apt-repository -y ppa:apt-fast/stable
sudo apt-get update
sudo apt-get install apt-fast
# install the actual dependencies
sudo apt-fast -y update
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 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 &
git clone git://github.com/libevent/libevent.git --quiet &
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 &
# wait until all background processes finished
FAIL=0
for job in `jobs -p`
do
echo "waiting for background job $job"
wait $job || let "FAIL+=1"
done
if [ "$FAIL" == "0" ];
then
echo "all downloads finished"
else
echo "$FAIL errors while downloading!"
exit 100
fi
# libevent
cd libevent
git checkout release-1.4.14b-stable
cat ../hphp/third_party/libevent-1.4.14.fb-changes.diff | patch -p1
./autogen.sh
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
# curl
cd curl
./buildconf
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
# glog
cd google-glog
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
# jemaloc
tar xjvf jemalloc-3.0.0.tar.bz2
cd jemalloc-3.0.0
./configure --prefix=$CMAKE_PREFIX_PATH
make
make install
cd ..
# cleanup
rm -rf libevent curl google-glog jemalloc-3.0.0.tar.bz2 jemalloc-3.0.0
# hphp
cmake .
echo "-------------------------------------------------------------------------"
echo "Done. Now run:"
echo " CMAKE_PREFIX_PATH=\`pwd\`/.. HPHP_HOME=\`pwd\` make"
+42 -24
Ver Arquivo
@@ -22,32 +22,42 @@ SET(USE_HHVM TRUE)
SET(ENV{HHVM} 1)
ADD_DEFINITIONS("-DHHVM -DHHVM_BINARY=1 -DHHVM_PATH=\\\"${HPHP_HOME}/hphp/hhvm/hhvm\\\"")
set(RECURSIVE_SOURCE_SUBDIRS runtime/base runtime/debugger runtime/eval runtime/ext runtime/server runtime/vm)
set(RECURSIVE_SOURCE_SUBDIRS runtime/base runtime/eval runtime/ext runtime/vm system util)
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})
# Disable hardware counters off of Linux
if(NOT LINUX)
add_definitions(-DNO_HARDWARE_COUNTERS)
list(REMOVE_ITEM CXX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/runtime/vm/debug/elfwriter.cpp)
list(REMOVE_ITEM CXX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/runtime/base/hardware_counter.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
# remove ext_hhvm, util/tests, and runtime/vm/translator/test
foreach (file ${CXX_SOURCES})
if (${file} MATCHES "ext_hhvm")
list(REMOVE_ITEM CXX_SOURCES ${file})
endif()
if (${file} MATCHES "/test/")
if (${file} MATCHES "util/test")
list(REMOVE_ITEM CXX_SOURCES ${file})
endif()
if (${file} MATCHES "runtime/vm/translator/test")
list(REMOVE_ITEM CXX_SOURCES ${file})
endif()
if (${file} MATCHES "runtime/vm/translator/hopt/test")
list(REMOVE_ITEM CXX_SOURCES ${file})
endif()
endforeach(file ${CXX_SOURCES})
# remove ext/sep for hhvm
foreach (file ${CXX_SOURCES})
if (${file} MATCHES "ext/sep")
list(REMOVE_ITEM CXX_SOURCES ${file})
endif()
endforeach(file ${CXX_SOURCES})
@@ -55,6 +65,10 @@ endforeach(file ${CXX_SOURCES})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
if (NOT SKIP_BUNDLED_XHP)
add_subdirectory(third_party/xhp/xhp)
endif()
add_subdirectory(third_party/libafdt)
add_subdirectory(third_party/libmbfl)
add_subdirectory(third_party/libsqlite3)
@@ -63,8 +77,25 @@ add_subdirectory(third_party/lz4)
add_subdirectory(third_party/double-conversion)
add_subdirectory(third_party/folly)
ADD_LIBRARY(hphp_runtime_static STATIC
${CXX_SOURCES} ${C_SOURCES} ${ASM_SOURCES})
foreach (CXX_FILE ${CXX_SOURCES})
if(${CXX_FILE} MATCHES ".no.cpp$")
SET_SOURCE_FILES_PROPERTIES(
${CXX_FILE}
PROPERTIES
COMPILE_FLAGS -O0
)
endif()
endforeach()
add_custom_command(
OUTPUT runtime/vm/repo_schema.h
COMMAND hphp/tools/generate_repo_schema.sh
DEPENDS ${CXX_SOURCES} ${C_SOURCES}
WORKING_DIRECTORY ${HPHP_HOME}
COMMENT "Generating Repo Schema ID"
VERBATIM)
ADD_LIBRARY(hphp_runtime_static STATIC runtime/vm/repo_schema.h ${CXX_SOURCES} ${C_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)
@@ -72,24 +103,11 @@ 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)
add_subdirectory(parser)
add_subdirectory(zend)
add_subdirectory(util)
add_subdirectory(compiler)
add_subdirectory(runtime/ext_hhvm)
add_subdirectory(hhvm)
add_subdirectory(system)
if (NOT "$ENV{HPHP_NOTEST}" STREQUAL "1")
add_subdirectory(test)
endif ()
# Keep this last
add_subdirectory(tools/hphpize)
-117
Ver Arquivo
@@ -1,117 +0,0 @@
Next release
- <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
- Support loading mini-systemlibs from extensions
"Tabasco" 30-Sep-2013
- Fix issues with __toString() functions that return non-string values
- Don't allow mock classes to extend collection classes
- Smarter memory allocation and scheduling for NUMA systems
- Improve profiler performance in the jit
- Fix several Zend compatibility issues
- Fix several bugs uncovered by ASAN
- Add collection support to array_keys, array_values, and array_combine
- Return a set-like array from Set::toArray
- Add to(Vector|Map|StableMap|Set) methods to collections
- Collections convert to boolean false when empty
- get_class_vars invokes the autoloader when necessary
- Rework the Zend compatibility layer to be more robust
- Allow traits to implement interfaces
- Support arbitrary expressions inside empty()
"Bobotie" 16-Sep-2013
- HNI (HipHop Native Interface) for calling C++ functions from Php
- Fix PropertyAccessorMap::isset
- Expose more POSIX constants
- Fixed behavior of stream_get_contents when default args are used.
- Implement str_getcsv, and fix some fgetcsv related issues.
- [IPv6] Fix stream_socket_recvfrom & stream_socket_sendto.
- [IPv6] Fix socket_sentto_recvfrom_ipv6_udp Zend compatibility.
- Optimize closure invocation and __invoke (~3x faster to invoke)
- Import gettext extension
- string and object allocation optimizations (reduced memory usage for both)
- Import YAML extension
- Import ftp extension
"Kimchi" 2-Sep-2013
- Fix order of custom attributes and visibility in ctor arg promotion
- Implement CachingIterator
- Implement RecursiveCachingIterator
- Generalized heuristic for choosing when to inline in the jit
- Introduced a Zend compatibility layer to compile extensions
- Imported calendar extension
- Use gcc-4.8.1 by default
- Improve hhvm commandline parsing logic
- Fix register_shutdown in session_set_save_handler to match PHP 5.4
- Add "native" functions for use in Systemlib
- PHP extension source-compatitblility layer
- Fix ArrayIterator constructor PHP compatibility
- Enable building against libmemcached 1.0.8
- Debugger: $_ not cleared but still printed after exception
- Fix clone of SplPriorityQueue
- Debugger: Fix bugs when multiple threads hit the same breakpoint
- Fix several namespace bugs
- Several PHP compatibility fixes for ArrayObject and ArrayIterator
- Fix list assignment with collection literals
- support "tuple(...)" in initializer expressions
- HHVM should compile with libmemcached 1.0.9+
- Support "(new Vector {..})->method()" style syntax
- use trigger_error in PHP for Redis user errors
- multiple simplexml fixes
- fixed serialize/unserialize for SplObjectStorage
- Implement ReflectionParameter::IsCallable()
"Achiote" 19-Aug-2013
- Async stack traces in the debugger via the "wa" command
- Fix late static binding in static closures
- Fix breakpoints on generators
- Add SplObserver and SplSubject interfaces
- Update Iterable interface and add toArray() method
- Allow __get for undefined properties
- Implement get_included_files()
- Limit use of huge pages
"Churrasco" 05-Aug-2013
- Implement stream_is_local
- Implement read support for .phar
- Implement assert with string arguments
- Implement RecursiveArrayIterator
- Implement php_strip_whitespace()
- Support for timeouts in cli mode
- Closure allocation optimizations (~2x faster to allocate a closure)
- Implement Redis session handler
- New memory profiler, hhprof, with pprof compatible output
- Update isset($string[$k]) and empty($string[$k) to PHP 5.5 semantics
- Fixed a few parser bugs
- Fixed a few bugs with token_get_all()
- Fix (string)$obj semantics when __toString() is not defined
"Tamale" 22-Jul-2013
- Optimize vector-shaped Arrays (arrays with keys in range 0..size-1)
- Enable HHBC by default in debug builds
- Implement SplObjectStorage::getInfo()
- Initial rough draft of xhpast2, a replacement for xhpast
- fix compilation on Ubuntu 13.04
- OSX changes, next round
- Modify PHP's ext/standard/math/tests/(pow|abs).phpt to be HHVM friendly
- add XHP comment syntax based on http://www.w3.org/TR/REC-xml/#sec-comments
"Wasabi Peas" 08-Jul-2013
- always_assert when we run out of TC space
- Initial changes to get HHVM compiling on OSX
- Consolodate ObjectData and Instance
- Prototype heap tracing framework & Heap profiler
- Better JIT code generation for Mod and Div
- Fixes to enable compilation with clang
- Support for yield k => v
- Make HHVM's command line parsing closer to PHP
- Implement Redis extension
- Implement LimitIterator from SPL
- add SessionHandler from PHP 5.4
- Numerous Debugger fixes and new developer docs for Debugger
- Ported many extension tests to PHP
-1
Ver Arquivo
@@ -49,4 +49,3 @@ add_definitions(-DALWAYS_ASSERT=1)
ADD_LIBRARY(hphp_analysis STATIC ${CXX_SOURCES} ${C_SOURCES})
target_link_libraries(hphp_analysis ${Boost_LIBRARIES})
add_dependencies(hphp_analysis hphp_parser)
+283 -305
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,66 +14,58 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/alias_manager.h"
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/expression/expression.h>
#include <compiler/expression/assignment_expression.h>
#include <compiler/expression/array_element_expression.h>
#include <compiler/expression/list_assignment.h>
#include <compiler/expression/binary_op_expression.h>
#include <compiler/expression/unary_op_expression.h>
#include <compiler/expression/qop_expression.h>
#include <compiler/expression/simple_variable.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/simple_function_call.h>
#include <compiler/expression/array_element_expression.h>
#include <compiler/expression/object_property_expression.h>
#include <compiler/expression/object_method_expression.h>
#include <compiler/expression/parameter_expression.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/expression.h>
#include <compiler/expression/include_expression.h>
#include <compiler/expression/closure_expression.h>
#include <compiler/statement/statement.h>
#include <compiler/statement/statement_list.h>
#include <compiler/statement/catch_statement.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/block_statement.h>
#include <compiler/statement/if_statement.h>
#include <compiler/statement/if_branch_statement.h>
#include <compiler/statement/break_statement.h>
#include <compiler/statement/return_statement.h>
#include <compiler/statement/loop_statement.h>
#include <compiler/statement/foreach_statement.h>
#include <compiler/statement/for_statement.h>
#include <compiler/statement/while_statement.h>
#include <compiler/statement/do_statement.h>
#include <compiler/statement/exp_statement.h>
#include <compiler/statement/echo_statement.h>
#include <compiler/statement/try_statement.h>
#include <compiler/analysis/alias_manager.h>
#include <compiler/analysis/control_flow.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/data_flow.h>
#include <compiler/analysis/dictionary.h>
#include <compiler/analysis/expr_dict.h>
#include <compiler/analysis/live_dict.h>
#include <compiler/analysis/ref_dict.h>
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/assignment_expression.h"
#include "hphp/compiler/expression/array_element_expression.h"
#include "hphp/compiler/expression/list_assignment.h"
#include "hphp/compiler/expression/binary_op_expression.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/compiler/expression/qop_expression.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/compiler/expression/array_element_expression.h"
#include "hphp/compiler/expression/object_property_expression.h"
#include "hphp/compiler/expression/object_method_expression.h"
#include "hphp/compiler/expression/parameter_expression.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/include_expression.h"
#include "hphp/compiler/expression/closure_expression.h"
#include "hphp/compiler/expression/yield_expression.h"
#include "hphp/compiler/expression/await_expression.h"
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/statement/catch_statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/block_statement.h"
#include "hphp/compiler/statement/if_statement.h"
#include "hphp/compiler/statement/if_branch_statement.h"
#include "hphp/compiler/statement/switch_statement.h"
#include "hphp/compiler/statement/break_statement.h"
#include "hphp/compiler/statement/return_statement.h"
#include "hphp/compiler/statement/loop_statement.h"
#include "hphp/compiler/statement/foreach_statement.h"
#include "hphp/compiler/statement/for_statement.h"
#include "hphp/compiler/statement/while_statement.h"
#include "hphp/compiler/statement/do_statement.h"
#include "hphp/compiler/statement/exp_statement.h"
#include "hphp/compiler/statement/echo_statement.h"
#include "hphp/compiler/statement/try_statement.h"
#include "hphp/compiler/statement/global_statement.h"
#include "hphp/compiler/statement/static_statement.h"
#include "hphp/compiler/analysis/control_flow.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/data_flow.h"
#include "hphp/compiler/analysis/dictionary.h"
#include "hphp/compiler/analysis/expr_dict.h"
#include "hphp/compiler/analysis/live_dict.h"
#include "hphp/compiler/analysis/ref_dict.h"
#include <util/parser/hphp.tab.hpp>
#include <util/parser/location.h>
#include <util/util.h>
#include "hphp/runtime/base/builtin-functions.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/parser/location.h"
#include "hphp/util/util.h"
#define spc(T,p) static_pointer_cast<T>(p)
#define dpc(T,p) dynamic_pointer_cast<T>(p)
#define spc(T,p) boost::static_pointer_cast<T>(p)
#define dpc(T,p) boost::dynamic_pointer_cast<T>(p)
using namespace HPHP;
using std::string;
@@ -268,7 +260,7 @@ void AliasManager::beginScope() {
ExpressionPtr e(new ScalarExpression(BlockScopePtr(), LocationPtr(),
T_STRING, string("begin")));
m_accessList.add(e);
m_stack.push_back(CondStackElem(m_accessList.size()));
m_stack.push_back(m_accessList.size());
m_accessList.beginScope();
if (BucketMapEntry *tail = m_bucketList) {
BucketMapEntry *bm = tail;
@@ -540,7 +532,11 @@ int AliasManager::testAccesses(ExpressionPtr e1, ExpressionPtr e2,
goto def;
}
case Expression::KindOfIncludeExpression: {
return InterfAccess;
IncludeExpressionPtr inc(spc(IncludeExpression, e2));
if (!inc->isPrivateScope()) {
return InterfAccess;
}
goto def;
}
case Expression::KindOfStaticMemberExpression:
case Expression::KindOfObjectPropertyExpression:
@@ -606,14 +602,10 @@ void AliasManager::cleanRefs(ExpressionPtr e,
ExpressionPtrList::reverse_iterator it,
ExpressionPtrList::reverse_iterator &end,
int depth) {
if (e->is(Expression::KindOfUnaryOpExpression) &&
e->getLocalEffects() == Expression::UnknownEffect) {
return;
}
if (e->is(Expression::KindOfAssignmentExpression) ||
e->is(Expression::KindOfBinaryOpExpression) ||
e->is(Expression::KindOfUnaryOpExpression)) {
ExpressionPtr var = e->getStoreVariable();
ExpressionPtr var = e->getNthExpr(0);
if (var->is(Expression::KindOfSimpleVariable) &&
!(var->getContext() & Expression::RefAssignmentLHS)) {
SimpleVariablePtr sv(spc(SimpleVariable, var));
@@ -748,11 +740,19 @@ void AliasManager::killLocals() {
goto kill_it;
case Expression::KindOfBinaryOpExpression:
if (!(effects & emask) &&
getOpForAssignmentOp(spc(BinaryOpExpression, e)->getOp())) {
if (okToKill(spc(BinaryOpExpression, e)->getExp1(), false)) {
e->setContext(Expression::DeadStore);
m_replaced++;
++it;
continue;
}
}
cleanInterf(spc(BinaryOpExpression, e)->getExp1(), ++it, end, depth);
continue;
case Expression::KindOfUnaryOpExpression:
if (e->getLocalEffects() == Expression::UnknownEffect) goto kill_it;
cleanInterf(spc(UnaryOpExpression, e)->getExpression(),
++it, end, depth);
continue;
@@ -850,33 +850,17 @@ int AliasManager::checkInterf(ExpressionPtr rv, ExpressionPtr e,
}
case Expression::KindOfUnaryOpExpression:
if (e->getLocalEffects() == Expression::UnknownEffect) {
isLoad = false;
return InterfAccess;
}
// fall through
case Expression::KindOfAssignmentExpression:
case Expression::KindOfBinaryOpExpression: {
isLoad = false;
ExpressionPtr var = e->getStoreVariable();
int access = testAccesses(var, rv, forLval);
if (access == SameAccess) {
// An assignment to something that might be visible from
// another scope, and that might contain an object, could
// end up with some other value (due to a destructor running)
// than the rhs.
if (var->getKindOf() != Expression::KindOfSimpleVariable) {
return InterfAccess;
}
SimpleVariablePtr sv = static_pointer_cast<SimpleVariable>(var);
if (sv->couldBeAliased() &&
(sv->isNeededValid() ? sv->isNeeded() :
!sv->getSymbol() || sv->getSymbol()->isNeeded())) {
return InterfAccess;
}
}
return access;
}
return testAccesses(
spc(UnaryOpExpression,e)->getExpression(), rv, forLval);
case Expression::KindOfBinaryOpExpression:
isLoad = false;
return testAccesses(
spc(BinaryOpExpression,e)->getExp1(), rv, forLval);
case Expression::KindOfAssignmentExpression:
isLoad = false;
return testAccesses(
spc(AssignmentExpression,e)->getVariable(), rv, forLval);
default:
not_reached();
@@ -903,13 +887,11 @@ int AliasManager::checkAnyInterf(ExpressionPtr e1, ExpressionPtr e2,
return DisjointAccess;
}
case Expression::KindOfAssignmentExpression:
case Expression::KindOfBinaryOpExpression:
e1 = spc(AssignmentExpression, e1)->getVariable();
break;
case Expression::KindOfUnaryOpExpression:
if (e1->getLocalEffects() == Expression::UnknownEffect) {
isLoad = false;
return InterfAccess;
}
e1 = e1->getStoreVariable();
case Expression::KindOfBinaryOpExpression:
e1 = e1->getNthExpr(0);
if (!e1 || !e1->hasContext(Expression::OprLValue)) return DisjointAccess;
break;
default:
@@ -1087,10 +1069,14 @@ void AliasManager::setCanonPtrForArrayCSE(
// need to switch on rep
ExpressionPtr rep0;
switch (rep->getKindOf()) {
case Expression::KindOfAssignmentExpression:
case Expression::KindOfBinaryOpExpression:
case Expression::KindOfUnaryOpExpression:
rep0 = rep->getStoreVariable();
rep0 = spc(UnaryOpExpression, rep)->getExpression();
break;
case Expression::KindOfBinaryOpExpression:
rep0 = spc(BinaryOpExpression, rep)->getExp1();
break;
case Expression::KindOfAssignmentExpression:
rep0 = spc(AssignmentExpression, rep)->getVariable();
break;
case Expression::KindOfListAssignment:
// TODO: IMPLEMENT
@@ -1170,12 +1156,11 @@ ExpressionPtr AliasManager::canonicalizeNode(
return ExpressionPtr();
}
ExpressionPtr var;
switch (e->getKindOf()) {
case Expression::KindOfAssignmentExpression: {
case Expression::KindOfAssignmentExpression:
case Expression::KindOfBinaryOpExpression:
case Expression::KindOfUnaryOpExpression:
ExpressionPtr var = e->getStoreVariable();
case Expression::KindOfUnaryOpExpression: {
ExpressionPtr var = e->getNthExpr(0);
if (var && var->getContext() & (Expression::AssignmentLHS|
Expression::OprLValue)) {
processAccessChain(var);
@@ -1284,7 +1269,6 @@ ExpressionPtr AliasManager::canonicalizeNode(
}
case Expression::KindOfUnaryOpExpression: {
UnaryOpExpressionPtr u = spc(UnaryOpExpression, rep);
assert(u->getOp() == T_INC || u->getOp() == T_DEC);
if (Option::EliminateDeadCode) {
if (u->getActualType() && u->getActualType()->isInteger()) {
ExpressionPtr val = u->getExpression()->clone();
@@ -1403,7 +1387,7 @@ ExpressionPtr AliasManager::canonicalizeNode(
value = value->replaceValue(
canonicalizeRecurNonNull(
value->makeConstant(m_arp, "null")));
a->setValue(value);
a->setNthKid(1, value);
a->recomputeEffects();
setChanged();
} else {
@@ -1414,7 +1398,7 @@ ExpressionPtr AliasManager::canonicalizeNode(
a = spc(AssignmentExpression, a->clone());
el->addElement(a);
el->addElement(a->getValue());
a->setValue(value->makeConstant(m_arp, "null"));
a->setNthKid(1, value->makeConstant(m_arp, "null"));
rep->setReplacement(el);
m_replaced++;
}
@@ -1519,7 +1503,8 @@ ExpressionPtr AliasManager::canonicalizeNode(
e->is(Expression::KindOfSimpleVariable) &&
!e->isThis()) {
Symbol *s = spc(SimpleVariable, e)->getSymbol();
if (s && !s->isParameter() && !s->isClosureVar()) {
if (s && !s->isParameter() && !s->isGeneratorParameter() &&
!s->isClosureVar()) {
rep = e->makeConstant(m_arp, "null");
Compiler::Error(Compiler::UseUndeclaredVariable, e);
if (m_variables->getAttribute(VariableTable::ContainsCompact)) {
@@ -1579,17 +1564,16 @@ ExpressionPtr AliasManager::canonicalizeNode(
cur = next;
}
if (!m_inCall &&
!last->is(Expression::KindOfAwaitExpression) &&
!last->is(Expression::KindOfYieldExpression) &&
ae->isUnused() && m_accessList.isLast(ae) &&
!e->hasAnyContext(Expression::AccessContext |
Expression::ObjectContext |
Expression::ExistContext |
Expression::UnsetContext)) {
!(Option::OutputHHBC &&
e->hasAnyContext(Expression::AccessContext |
Expression::ObjectContext |
Expression::ExistContext |
Expression::UnsetContext))) {
rep = ae->clone();
ae->setContext(Expression::DeadStore);
ae->setValue(ae->makeConstant(m_arp, "null"));
ae->setVariable(ae->makeConstant(m_arp, "null"));
ae->setNthKid(1, ae->makeConstant(m_arp, "null"));
ae->setNthKid(0, ae->makeConstant(m_arp, "null"));
e->recomputeEffects();
m_replaced++;
return e->replaceValue(canonicalizeRecurNonNull(rep));
@@ -1676,7 +1660,7 @@ ExpressionPtr AliasManager::canonicalizeNode(
while (v->getCanonPtr() && v->getCanonPtr() != op0) {
v = v->getCanonPtr();
}
ok = (v->getCanonPtr() != nullptr);
ok = v->getCanonPtr();
}
if (ok) {
b2->setContext(Expression::DeadStore);
@@ -1724,15 +1708,18 @@ ExpressionPtr AliasManager::canonicalizeNode(
if (interf == SameAccess) {
switch (alt->getKindOf()) {
case Expression::KindOfAssignmentExpression:
alt = spc(AssignmentExpression,alt)->getVariable();
break;
case Expression::KindOfBinaryOpExpression:
alt = spc(BinaryOpExpression,alt)->getExp1();
break;
case Expression::KindOfUnaryOpExpression:
alt = alt->getStoreVariable();
alt = spc(UnaryOpExpression,alt)->getExpression();
break;
default:
break;
}
always_assert(alt->getKindOf() ==
uop->getExpression()->getKindOf());
always_assert(alt->getKindOf() == uop->getExpression()->getKindOf());
uop->getExpression()->setCanonID(alt->getCanonID());
} else {
uop->getExpression()->setCanonID(m_nextID++);
@@ -1741,11 +1728,7 @@ ExpressionPtr AliasManager::canonicalizeNode(
add(m_accessList, e);
break;
default:
if (uop->getLocalEffects() == Expression::UnknownEffect) {
add(m_accessList, e);
} else {
getCanonical(e);
}
getCanonical(e);
break;
}
break;
@@ -1772,8 +1755,6 @@ ExpressionPtr AliasManager::canonicalizeNode(
}
void AliasManager::canonicalizeKid(ConstructPtr c, ExpressionPtr kid, int i) {
assert(c->getNthKid(i) == kid);
if (kid) {
StatementPtr sp(dpc(Statement, c));
if (sp) beginInExpression(sp, kid);
@@ -1793,8 +1774,6 @@ void AliasManager::canonicalizeKid(ConstructPtr c, ExpressionPtr kid, int i) {
}
int AliasManager::canonicalizeKid(ConstructPtr c, ConstructPtr kid, int i) {
assert(c->getNthKid(i) == kid);
int ret = FallThrough;
if (kid) {
ExpressionPtr e = dpc(Expression, kid);
@@ -1828,34 +1807,51 @@ ExpressionPtr AliasManager::canonicalizeRecur(ExpressionPtr e) {
bool setInCall = true;
switch (e->getKindOf()) {
case Expression::KindOfQOpExpression: {
QOpExpressionPtr qe(spc(QOpExpression, e));
canonicalizeKid(e, qe->getCondition(), 0);
case Expression::KindOfQOpExpression:
canonicalizeKid(e, e->getNthExpr(0), 0);
beginScope();
if (ExpressionPtr e1 = qe->getYes()) {
if (ExpressionPtr e1 = e->getNthExpr(1)) {
canonicalizeKid(e, e1, 1);
resetScope();
}
canonicalizeKid(e, qe->getNo(), 2);
canonicalizeKid(e, e->getNthExpr(2), 2);
endScope();
return canonicalizeNode(e);
}
case Expression::KindOfBinaryOpExpression: {
BinaryOpExpressionPtr binop(spc(BinaryOpExpression, e));
if (binop->isShortCircuitOperator()) {
canonicalizeKid(e, binop->getExp1(), 0);
beginScope();
canonicalizeKid(e, binop->getExp2(), 1);
endScope();
return canonicalizeNode(e);
case Expression::KindOfBinaryOpExpression:
{
BinaryOpExpressionPtr binop(spc(BinaryOpExpression, e));
if (binop->isShortCircuitOperator()) {
canonicalizeKid(e, e->getNthExpr(0), 0);
beginScope();
canonicalizeKid(e, e->getNthExpr(1), 1);
endScope();
return canonicalizeNode(e);
}
}
break;
}
case Expression::KindOfExpressionList:
delayVars = false;
break;
case Expression::KindOfSimpleFunctionCall:
if (!Option::OutputHHBC) {
SimpleFunctionCallPtr f(spc(SimpleFunctionCall, e));
if (!f->getClass()) {
if (f->getClassName().empty()) {
if (f->getFuncScope() &&
!f->getFuncScope()->isVolatile()) {
setInCall = false;
}
} else if (ClassScopePtr cls = f->resolveClass()) {
if (!cls->isVolatile()) {
setInCall = false;
}
}
}
}
// fall through
case Expression::KindOfNewObjectExpression:
case Expression::KindOfDynamicFunctionCall:
inCall = setInCall;
@@ -1877,7 +1873,6 @@ ExpressionPtr AliasManager::canonicalizeRecur(ExpressionPtr e) {
int n = e->getKidCount();
if (n < 2) delayVars = false;
if (e->is(Expression::KindOfAssignmentExpression)) delayVars = false;
m_inCall += inCall;
for (int j = delayVars ? 0 : 1; j < 2; j++) {
@@ -1947,42 +1942,42 @@ StatementPtr AliasManager::canonicalizeRecur(StatementPtr s, int &ret) {
// and fall through
break;
case Statement::KindOfIfStatement: {
IfStatementPtr is = spc(IfStatement, s);
StatementListPtr iflist = is->getIfBranches();
if (iflist) {
for (int i = 0, n = iflist->getKidCount(); i < n; i++) {
IfBranchStatementPtr ifstmt = spc(IfBranchStatement, (*iflist)[i]);
canonicalizeKid(ifstmt, ifstmt->getCondition(), 0);
if (!i) beginScope();
beginScope();
canonicalizeKid(ifstmt, ifstmt->getStmt(), 1);
case Statement::KindOfIfStatement:
{
StatementPtr iflist = spc(Statement, s->getNthKid(0));
if (iflist) {
for (int i = 0, n = iflist->getKidCount(); i < n; i++) {
StatementPtr ifstmt = spc(Statement, iflist->getNthKid(i));
ExpressionPtr cond = spc(Expression, ifstmt->getNthKid(0));
canonicalizeKid(ifstmt, cond, 0);
if (!i) beginScope();
beginScope();
canonicalizeKid(ifstmt, ifstmt->getNthKid(1), 1);
endScope();
if (i+1 < n) resetScope();
}
endScope();
if (i+1 < n) resetScope();
}
endScope();
ret = FallThrough;
start = nkid;
}
ret = FallThrough;
start = nkid;
break;
}
case Statement::KindOfIfBranchStatement:
always_assert(0);
break;
case Statement::KindOfForStatement: {
ForStatementPtr fs(spc(ForStatement, s));
canonicalizeKid(s, fs->getInitExp(), 0);
case Statement::KindOfForStatement:
canonicalizeKid(s, spc(Expression,s->getNthKid(0)), 0);
clear();
canonicalizeKid(s, fs->getCondExp(), 1);
canonicalizeKid(s, fs->getBody(), 2);
canonicalizeKid(s, spc(Expression,s->getNthKid(1)), 1);
canonicalizeKid(s, s->getNthKid(2), 2);
clear();
canonicalizeKid(s, fs->getIncExp(), 3);
canonicalizeKid(s, spc(Expression,s->getNthKid(3)), 3);
ret = Converge;
start = nkid;
break;
}
case Statement::KindOfWhileStatement:
case Statement::KindOfDoStatement:
case Statement::KindOfForEachStatement:
@@ -1990,27 +1985,27 @@ StatementPtr AliasManager::canonicalizeRecur(StatementPtr s, int &ret) {
ret = Converge;
break;
case Statement::KindOfSwitchStatement: {
SwitchStatementPtr ss(spc(SwitchStatement, s));
canonicalizeKid(s, ss->getExp(), 0);
case Statement::KindOfSwitchStatement:
canonicalizeKid(s, spc(Expression,s->getNthKid(0)), 0);
clear();
start = 1;
ret = Converge;
break;
}
case Statement::KindOfCaseStatement:
case Statement::KindOfLabelStatement:
clear();
break;
case Statement::KindOfReturnStatement: {
ReturnStatementPtr rs(spc(ReturnStatement, s));
canonicalizeKid(s, rs->getRetExp(), 0);
case Statement::KindOfReturnStatement:
{
canonicalizeKid(s, spc(Expression,s->getNthKid(0)), 0);
killLocals();
ret = FallThrough;
start = nkid;
break;
}
case Statement::KindOfBreakStatement:
case Statement::KindOfContinueStatement:
case Statement::KindOfGotoStatement:
@@ -2037,9 +2032,6 @@ StatementPtr AliasManager::canonicalizeRecur(StatementPtr s, int &ret) {
break;
}
case Statement::KindOfTypedefStatement:
break;
case Statement::KindOfCatchStatement:
clear();
ret = Converge;
@@ -2108,7 +2100,6 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) {
}
cs->clearVisited();
cs->clearChildOfYield();
StatementPtr s = dpc(Statement, cs);
if (s) {
@@ -2140,10 +2131,7 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) {
case Statement::KindOfGlobalStatement:
case Statement::KindOfStaticStatement:
{
ExpressionListPtr vars = (skind == Statement::KindOfGlobalStatement)
? spc(GlobalStatement, s)->getVars()
: spc(StaticStatement, s)->getVars();
ExpressionListPtr vars = dpc(ExpressionList, s->getNthKid(0));
for (int i = 0, n = vars->getCount(); i < n; i++) {
ExpressionPtr e = (*vars)[i];
if (AssignmentExpressionPtr ae = dpc(AssignmentExpression, e)) {
@@ -2199,18 +2187,17 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) {
}
break;
case Statement::KindOfForEachStatement: {
ForEachStatementPtr fs(static_pointer_cast<ForEachStatement>(s));
SimpleVariablePtr name = dpc(SimpleVariable, fs->getNameExp());
SimpleVariablePtr name =
dpc(SimpleVariable, s->getNthKid(ForEachStatement::NameExpr));
if (name) {
if (Symbol *sym = name->getSymbol()) {
sym->setNeeded();
}
Symbol *sym = name->getSymbol();
sym->setNeeded();
}
SimpleVariablePtr value = dpc(SimpleVariable, fs->getValueExp());
SimpleVariablePtr value =
dpc(SimpleVariable, s->getNthKid(ForEachStatement::ValueExpr));
if (value) {
if (Symbol *sym = value->getSymbol()) {
sym->setNeeded();
}
Symbol *sym = value->getSymbol();
sym->setNeeded();
}
break;
}
@@ -2325,7 +2312,9 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) {
case Expression::KindOfIncludeExpression:
{
IncludeExpressionPtr inc(spc(IncludeExpression, e));
m_variables->setAttribute(VariableTable::ContainsLDynamicVariable);
if (!inc->isPrivateScope()) {
m_variables->setAttribute(VariableTable::ContainsLDynamicVariable);
}
}
break;
case Expression::KindOfArrayElementExpression:
@@ -2399,9 +2388,6 @@ 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) {
@@ -2424,14 +2410,14 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) {
}
break;
}
case Expression::KindOfQOpExpression: {
QOpExpressionPtr q(spc(QOpExpression, e));
case Expression::KindOfQOpExpression:
if (unused) {
if (ExpressionPtr t1 = q->getYes()) t1->setUnused(true);
q->getNo()->setUnused(true);
if (ExpressionPtr t1 = e->getNthExpr(1)) t1->setUnused(true);
e->getNthExpr(2)->setUnused(true);
}
break;
}
default:
break;
}
@@ -2526,7 +2512,7 @@ static void markAvailable(ExpressionRawPtr e) {
class TypeAssertionInserter {
public:
explicit TypeAssertionInserter(AnalysisResultConstPtr ar) :
TypeAssertionInserter(AnalysisResultConstPtr ar) :
m_ar(ar), m_changed(false) {
BuildAssertionMap();
}
@@ -2637,13 +2623,6 @@ private:
if (sv && se) {
const string &s = se->getLiteralString();
if (s.empty()) return ExpressionPtr();
if (interface_supports_array(s) ||
interface_supports_string(s) ||
interface_supports_int(s) ||
interface_supports_double(s)) {
// This could be a primitive type, so don't assert anything
return ExpressionPtr();
}
TypePtr o(Type::CreateObjectType(Util::toLower(s)));
// don't do specific type assertions for unknown classes
@@ -2977,6 +2956,15 @@ private:
}
}
break;
case Statement::KindOfBreakStatement:
{
BreakStatementPtr bs(spc(BreakStatement, stmt));
if (bs->getExp()) {
ExpressionPtr rep(
insertTypeAssertion(assertion, bs->getExp()));
replaceExpression(bs, rep, bs->getExp(), 0);
}
}
default:
// this is something like a continue statement,
// in which case we don't do anything
@@ -2988,9 +2976,8 @@ private:
if (!e) return ExpressionPtr();
if (FunctionWalker::SkipRecurse(e)) return ExpressionPtr();
ExpressionPtr loopCond;
StatementPtr loopBody;
std::vector<ExpressionPtr> needed;
int loopCondIdx = -1, loopBodyIdx = -1;
std::vector<int> needed;
switch (e->getKindOf()) {
case Statement::KindOfIfStatement:
{
@@ -3062,45 +3049,46 @@ private:
}
}
return ExpressionPtr();
case Statement::KindOfForStatement: {
ForStatementPtr fs(static_pointer_cast<ForStatement>(e));
loopCond = fs->getCondExp();
loopBody = fs->getBody();
needed.push_back(fs->getInitExp());
needed.push_back(fs->getIncExp());
case Statement::KindOfForStatement:
loopCondIdx = ForStatement::CondExpr;
loopBodyIdx = ForStatement::BodyStmt;
needed.push_back(ForStatement::InitExpr);
needed.push_back(ForStatement::IncExpr);
goto loop_stmt;
}
case Statement::KindOfWhileStatement: {
WhileStatementPtr ws(static_pointer_cast<WhileStatement>(e));
loopCond = ws->getCondExp();
loopBody = ws->getBody();
case Statement::KindOfWhileStatement:
loopCondIdx = WhileStatement::CondExpr;
loopBodyIdx = WhileStatement::BodyStmt;
goto loop_stmt;
}
case Statement::KindOfDoStatement: {
DoStatementPtr ds(static_pointer_cast<DoStatement>(e));
loopCond = ds->getCondExp();
loopBody = ds->getBody();
}
case Statement::KindOfDoStatement:
loopCondIdx = DoStatement::CondExpr;
loopBodyIdx = DoStatement::BodyStmt;
loop_stmt:
{
if (loopCond) {
assert(loopCondIdx >= 0);
assert(loopBodyIdx >= 0);
if (e->getNthKid(loopCondIdx)) {
bool passStmt;
bool negate;
ExpressionPtr after(createTypeAssertions(loopCond, passStmt, negate));
ExpressionPtr after(createTypeAssertions(
spc(Expression, e->getNthKid(loopCondIdx)), passStmt, negate));
if (after && !negate) {
insertTypeAssertion(after, loopBody);
insertTypeAssertion(
after, dpc(Statement, e->getNthKid(loopBodyIdx)));
}
}
for (auto it = needed.begin(); it != needed.end(); ++it) {
ExpressionPtr k(dpc(Expression, *it));
for (std::vector<int>::const_iterator it = needed.begin();
it != needed.end();
++it) {
ExpressionPtr k(dpc(Expression, e->getNthKid(*it)));
if (k) {
bool passStmt;
bool negate;
createTypeAssertions(k, passStmt, negate);
}
}
createTypeAssertions(loopBody);
ConstructPtr body(e->getNthKid(loopBodyIdx));
createTypeAssertions(dpc(Statement, body));
}
return ExpressionPtr();
case Statement::KindOfStatementList:
@@ -3327,12 +3315,19 @@ public:
DataFlowWalker::walk(*this);
ControlBlock *b = m_graph.getDfBlock(1);
std::map<std::string,int>::iterator it = m_gidMap.find("v:this");
if (it != m_gidMap.end() && it->second) {
b->setBit(DataFlow::PRefIn, it->second);
b->setBit(DataFlow::PInitIn, it->second);
if (m->getOrigGeneratorFunc()) {
BitOps::set(m_gidMap.size(), b->getRow(DataFlow::PRefIn),
BitOps::Bits(-1));
BitOps::set(m_gidMap.size(), b->getRow(DataFlow::PInitIn),
BitOps::Bits(-1));
} else {
if (it != m_gidMap.end() && it->second) {
b->setBit(DataFlow::PRefIn, it->second);
b->setBit(DataFlow::PInitIn, it->second);
}
updateParamInfo(m->getParams(), Option::HardTypeHints);
updateParamInfo(m->getFunctionScope()->getClosureVars(), false);
}
updateParamInfo(m->getParams(), Option::HardTypeHints);
updateParamInfo(m->getFunctionScope()->getClosureVars(), false);
}
void updateParamInfo(ExpressionListPtr el, bool useDefaults) {
@@ -3344,9 +3339,6 @@ public:
std::map<std::string,int>::iterator it =
m_gidMap.find("v:" + p->getName());
if (it != m_gidMap.end() && it->second) {
// NB: this is unsound if the user error handler swallows a
// parameter typehint failure. It's opt-in via compiler
// options, though.
if (useDefaults && p->hasTypeHint() && !p->defaultValue()) {
b->setBit(DataFlow::AvailIn, it->second);
}
@@ -3583,8 +3575,8 @@ public:
} else {
auto sym = vars->getSymbol(l);
auto dt = vars->getFinalType(l)->getDataType();
if (!sym->isStatic() && dt != KindOfUnknown &&
!IS_REFCOUNTED_TYPE(dt)) {
if (!sym->isStatic()
&& !IS_REFCOUNTED_TYPE(dt) && dt != KindOfUnknown) {
rs->addNonRefcounted(l);
}
}
@@ -3606,7 +3598,7 @@ public:
bool walk() { ControlFlowGraphWalker::walk(*this); return m_changed; }
int afterEach(ConstructRawPtr p, int i, ConstructPtr kid) {
if (ExpressionRawPtr e = dynamic_pointer_cast<Expression>(kid)) {
if (ExpressionRawPtr e = boost::dynamic_pointer_cast<Expression>(kid)) {
if (e->isTypeAssertion()) return WalkContinue; // nothing to do
bool safeForProp =
@@ -3921,8 +3913,7 @@ void AliasManager::invalidateChainRoots(StatementPtr s) {
// otherwise we'd have to declare all CSE temps like:
// declare_temps;
// do { ... } while (cond);
DoStatementPtr ds(static_pointer_cast<DoStatement>(s));
disableCSE(ds->getBody());
disableCSE(s->getNthStmt(DoStatement::BodyStmt));
}
// fall through
default:
@@ -3933,56 +3924,47 @@ void AliasManager::invalidateChainRoots(StatementPtr s) {
}
}
void AliasManager::nullSafeDisableCSE(StatementPtr parent, ExpressionPtr kid) {
void AliasManager::nullSafeDisableCSE(StatementPtr parent, int kid) {
assert(parent);
if (!kid) return;
kid->disableCSE();
ConstructPtr c(parent->getNthKid(kid));
if (!c) return;
ExpressionPtr e(dpc(Expression, c));
assert(e);
e->disableCSE();
}
void AliasManager::disableCSE(StatementPtr s) {
if (!s) return;
switch (s->getKindOf()) {
case Statement::KindOfIfBranchStatement: {
IfBranchStatementPtr is(static_pointer_cast<IfBranchStatement>(s));
nullSafeDisableCSE(s, is->getCondition());
case Statement::KindOfIfBranchStatement:
nullSafeDisableCSE(s, 0);
break;
}
case Statement::KindOfSwitchStatement: {
SwitchStatementPtr ss(static_pointer_cast<SwitchStatement>(s));
nullSafeDisableCSE(s, ss->getExp());
case Statement::KindOfSwitchStatement:
nullSafeDisableCSE(s, 0);
break;
}
case Statement::KindOfForStatement: {
ForStatementPtr fs(static_pointer_cast<ForStatement>(s));
nullSafeDisableCSE(s, fs->getInitExp());
nullSafeDisableCSE(s, fs->getCondExp());
nullSafeDisableCSE(s, fs->getIncExp());
case Statement::KindOfForStatement:
nullSafeDisableCSE(s, ForStatement::InitExpr);
nullSafeDisableCSE(s, ForStatement::CondExpr);
nullSafeDisableCSE(s, ForStatement::IncExpr);
break;
}
case Statement::KindOfForEachStatement: {
ForEachStatementPtr fs(static_pointer_cast<ForEachStatement>(s));
nullSafeDisableCSE(s, fs->getArrayExp());
nullSafeDisableCSE(s, fs->getNameExp());
nullSafeDisableCSE(s, fs->getValueExp());
case Statement::KindOfForEachStatement:
nullSafeDisableCSE(s, ForEachStatement::ArrayExpr);
nullSafeDisableCSE(s, ForEachStatement::NameExpr);
nullSafeDisableCSE(s, ForEachStatement::ValueExpr);
break;
}
case Statement::KindOfWhileStatement: {
WhileStatementPtr ws(static_pointer_cast<WhileStatement>(s));
nullSafeDisableCSE(s, ws->getCondExp());
case Statement::KindOfWhileStatement:
nullSafeDisableCSE(s, WhileStatement::CondExpr);
break;
}
case Statement::KindOfDoStatement: {
DoStatementPtr ds(static_pointer_cast<DoStatement>(s));
nullSafeDisableCSE(s, ds->getCondExp());
case Statement::KindOfDoStatement:
nullSafeDisableCSE(s, DoStatement::CondExpr);
break;
}
default:
for (int i = s->getKidCount(); i--; ) {
ConstructPtr c(s->getNthKid(i));
if (StatementPtr skid = dpc(Statement, c)) {
disableCSE(skid);
} else {
nullSafeDisableCSE(s, dpc(Expression, c));
nullSafeDisableCSE(s, i);
}
}
break;
@@ -4126,42 +4108,38 @@ void AliasManager::stringOptsRecur(StatementPtr s) {
}
break;
case Statement::KindOfForStatement: {
ForStatementPtr fs = spc(ForStatement, s);
stringOptsRecur(fs->getInitExp(), true);
case Statement::KindOfForStatement:
stringOptsRecur(spc(Expression,s->getNthKid(0)), true);
pushStringScope(s);
stringOptsRecur(fs->getCondExp(), false);
stringOptsRecur(fs->getBody());
stringOptsRecur(fs->getIncExp(), true);
stringOptsRecur(spc(Expression,s->getNthKid(1)), false);
stringOptsRecur(spc(Statement, s->getNthKid(2)));
stringOptsRecur(spc(Expression,s->getNthKid(3)), true);
popStringScope(s);
return;
}
case Statement::KindOfWhileStatement: {
WhileStatementPtr ws = spc(WhileStatement, s);
case Statement::KindOfWhileStatement:
pushStringScope(s);
stringOptsRecur(ws->getCondExp(), false);
stringOptsRecur(ws->getBody());
stringOptsRecur(spc(Expression,s->getNthKid(0)), false);
stringOptsRecur(spc(Statement, s->getNthKid(1)));
popStringScope(s);
return;
}
case Statement::KindOfDoStatement: {
DoStatementPtr ds = spc(DoStatement, s);
case Statement::KindOfDoStatement:
pushStringScope(s);
stringOptsRecur(ds->getBody());
stringOptsRecur(ds->getCondExp(), false);
stringOptsRecur(spc(Statement, s->getNthKid(0)));
stringOptsRecur(spc(Expression,s->getNthKid(1)), false);
popStringScope(s);
return;
}
case Statement::KindOfForEachStatement: {
ForEachStatementPtr fs = spc(ForEachStatement, s);
stringOptsRecur(fs->getArrayExp(), false);
stringOptsRecur(fs->getNameExp(), false);
stringOptsRecur(fs->getValueExp(), false);
case Statement::KindOfForEachStatement:
stringOptsRecur(spc(Expression,s->getNthKid(0)), false);
stringOptsRecur(spc(Expression,s->getNthKid(1)), false);
stringOptsRecur(spc(Expression,s->getNthKid(2)), false);
pushStringScope(s);
stringOptsRecur(fs->getBody());
stringOptsRecur(spc(Statement, s->getNthKid(3)));
popStringScope(s);
return;
}
case Statement::KindOfExpStatement:
stringOptsRecur(spc(ExpStatement,s)->getExpression(), true);
return;
+9 -9
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ALIAS_MANAGER_H_
#define incl_HPHP_ALIAS_MANAGER_H_
#ifndef __ALIAS_MANAGER_H__
#define __ALIAS_MANAGER_H__
#include "hphp/compiler/expression/expression.h"
#include <compiler/expression/expression.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -88,7 +88,7 @@ class AliasManager {
enum { SameAccess, SameLValueAccess, InterfAccess,
DisjointAccess, NotAccess };
explicit AliasManager(int opt);
AliasManager(int opt);
~AliasManager();
void clear();
@@ -141,7 +141,7 @@ class AliasManager {
enum { FallThrough, CondBranch, Branch, Converge };
enum { NoCopyProp = 1, NoDeadStore = 2 };
struct CondStackElem {
explicit CondStackElem(size_t s = 0) : m_size(s), m_exprs() {}
CondStackElem(size_t s = 0) : m_size(s), m_exprs() {}
size_t m_size;
ExpressionPtrList m_exprs;
};
@@ -154,7 +154,7 @@ class AliasManager {
class LoopInfo {
public:
explicit LoopInfo(StatementPtr s);
LoopInfo(StatementPtr s);
StatementPtr m_stmt;
StatementPtrVec m_inner;
@@ -205,7 +205,7 @@ class AliasManager {
StatementPtr canonicalizeRecur(StatementPtr e, int &ret);
void invalidateChainRoots(StatementPtr s);
void nullSafeDisableCSE(StatementPtr parent, ExpressionPtr kid);
void nullSafeDisableCSE(StatementPtr parent, int kid);
void disableCSE(StatementPtr s);
void createCFG(MethodStatementPtr m);
void deleteCFG();
@@ -276,4 +276,4 @@ class AliasManager {
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ALIAS_MANAGER_H_
#endif // __ALIAS_MANAGER_H__
+71 -154
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,47 +14,45 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/analysis_result.h"
#include <iomanip>
#include <algorithm>
#include <sstream>
#include <boost/format.hpp>
#include <boost/bind.hpp>
#include "hphp/compiler/analysis/alias_manager.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/depth_first_visitor.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/statement/if_branch_statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/loop_statement.h"
#include "hphp/compiler/statement/class_variable.h"
#include "hphp/compiler/statement/use_trait_statement.h"
#include "hphp/compiler/analysis/symbol_table.h"
#include "hphp/compiler/package.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/builtin_symbols.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/array_pair_expression.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/runtime/ext/ext_json.h"
#include "hphp/runtime/base/zend-printf.h"
#include "hphp/runtime/base/program-functions.h"
#include "hphp/util/atomic.h"
#include "hphp/util/logger.h"
#include "hphp/util/util.h"
#include "hphp/util/hash.h"
#include "hphp/util/process.h"
#include "hphp/util/job-queue.h"
#include "hphp/util/timer.h"
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/alias_manager.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/depth_first_visitor.h>
#include <compiler/statement/statement_list.h>
#include <compiler/statement/if_branch_statement.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/loop_statement.h>
#include <compiler/statement/class_variable.h>
#include <compiler/statement/use_trait_statement.h>
#include <compiler/analysis/symbol_table.h>
#include <compiler/package.h>
#include <compiler/parser/parser.h>
#include <compiler/option.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/builtin_symbols.h>
#include <compiler/analysis/constant_table.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/constant_expression.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/array_pair_expression.h>
#include <runtime/ext/ext_json.h>
#include <runtime/base/zend/zend_printf.h>
#include <runtime/base/program_functions.h>
#include <util/atomic.h>
#include <util/logger.h>
#include <util/util.h>
#include <util/hash.h>
#include <util/process.h>
#include <util/job_queue.h>
#include <util/timer.h>
using namespace HPHP;
using std::map;
@@ -159,10 +157,6 @@ void AnalysisResult::parseOnDemandBy(const string &name,
}
}
void AnalysisResult::addNSFallbackFunc(ConstructPtr c, FileScopePtr fs) {
m_nsFallbackFuncs.insert(std::make_pair(c, fs));
}
FileScopePtr AnalysisResult::findFileScope(const std::string &name) const {
StringToFileScopePtrMap::const_iterator iter = m_files.find(name);
if (iter != m_files.end()) {
@@ -175,7 +169,7 @@ FunctionScopePtr AnalysisResult::findFunction(
const std::string &funcName) const {
StringToFunctionScopePtrMap::const_iterator bit =
m_functions.find(funcName);
if (bit != m_functions.end() && !bit->second->allowOverride()) {
if (bit != m_functions.end()) {
return bit->second;
}
StringToFunctionScopePtrMap::const_iterator iter =
@@ -183,7 +177,7 @@ FunctionScopePtr AnalysisResult::findFunction(
if (iter != m_functionDecs.end()) {
return iter->second;
}
return bit != m_functions.end() ? bit->second : FunctionScopePtr();
return FunctionScopePtr();
}
BlockScopePtr AnalysisResult::findConstantDeclarer(
@@ -241,8 +235,8 @@ ClassScopePtr AnalysisResult::findClass(const std::string &name,
return ClassScopePtr();
}
const ClassScopePtrVec &
AnalysisResult::findRedeclaredClasses(const std::string &name) const {
const ClassScopePtrVec &AnalysisResult::findRedeclaredClasses
(const std::string &name) const {
StringToClassScopePtrVecMap::const_iterator iter = m_classDecs.find(name);
if (iter == m_classDecs.end()) {
static ClassScopePtrVec empty;
@@ -349,14 +343,11 @@ bool AnalysisResult::declareFunction(FunctionScopePtr funcScope) const {
string fname = funcScope->getName();
// System functions override
auto it = m_functions.find(fname);
if (it != m_functions.end()) {
if (!it->second->allowOverride()) {
// we need someone to hold on to a reference to it
// even though we're not going to do anything with it
this->lock()->m_ignoredScopes.push_back(funcScope);
return false;
}
if (m_functions.find(fname) != m_functions.end()) {
// we need someone to hold on to a reference to it
// even though we're not going to do anything with it
this->lock()->m_ignoredScopes.push_back(funcScope);
return false;
}
return true;
@@ -408,9 +399,7 @@ static bool by_source(const BlockScopePtr &b1, const BlockScopePtr &b2) {
void AnalysisResult::canonicalizeSymbolOrder() {
getConstants()->canonicalizeSymbolOrder();
getVariables()->canonicalizeSymbolOrder();
}
void AnalysisResult::markRedeclaringClasses() {
AnalysisResultPtr ar = shared_from_this();
for (StringToClassScopePtrVecMap::iterator iter = m_classDecs.begin();
iter != m_classDecs.end(); ++iter) {
@@ -422,56 +411,6 @@ void AnalysisResult::markRedeclaringClasses() {
}
}
}
auto markRedeclaring = [&] (const std::string& name) {
auto it = m_classDecs.find(name);
if (it != m_classDecs.end()) {
auto& classes = it->second;
for (unsigned int i = 0; i < classes.size(); ++i) {
classes[i]->setRedeclaring(ar, i);
}
}
};
/*
* In WholeProgram mode, during parse time we collected all
* class_alias calls so we can mark the targets of such calls
* redeclaring if necessary.
*
* Two cases here that definitely require this:
*
* - If an alias name has the same name as another class, we need
* to mark *that* class as redeclaring, since it may mean
* different things in different requests now.
*
* - If an alias name can refer to more than one class, each of
* those classes must be marked redeclaring.
*
* In the simple case of a unique alias name and a unique target
* name, we might be able to get away with manipulating the target
* classes' volatility.
*
* Rather than work through the various cases here, though, we've
* just decided to just play it safe and mark all the names involved
* as redeclaring for now.
*/
for (auto& kv : m_classAliases) {
assert(kv.first == Util::toLower(kv.first));
assert(kv.second == Util::toLower(kv.second));
markRedeclaring(kv.first);
markRedeclaring(kv.second);
}
/*
* Similar to class_alias, when a type alias is declared with the
* same name as a class in the program, we need to make sure the
* class is marked redeclaring. It is possible in some requests
* that things like 'instanceof Foo' will not mean the same thing.
*/
for (auto& name : m_typeAliasNames) {
assert(Util::toLower(name) == name);
markRedeclaring(name);
}
}
///////////////////////////////////////////////////////////////////////////////
@@ -570,6 +509,11 @@ bool AnalysisResult::isSystemConstant(const std::string &constName) const {
///////////////////////////////////////////////////////////////////////////////
// Program
void AnalysisResult::loadBuiltinFunctions() {
AnalysisResultPtr ar = shared_from_this();
BuiltinSymbols::LoadFunctions(ar, m_functions);
}
void AnalysisResult::loadBuiltins() {
AnalysisResultPtr ar = shared_from_this();
BuiltinSymbols::LoadFunctions(ar, m_functions);
@@ -586,24 +530,13 @@ void AnalysisResult::checkClassDerivations() {
BOOST_FOREACH(cls, iter->second) {
hphp_string_iset seen;
cls->checkDerivation(ar, seen);
if (Option::WholeProgram) {
if (Option::WholeProgram || !Option::OutputHHBC) {
cls->importUsedTraits(ar);
}
}
}
}
void AnalysisResult::resolveNSFallbackFuncs() {
for (auto &pair : m_nsFallbackFuncs) {
SimpleFunctionCallPtr sfc =
static_pointer_cast<SimpleFunctionCall>(pair.first);
sfc->resolveNSFallbackFunc(
shared_from_this(),
pair.second
);
}
}
void AnalysisResult::collectFunctionsAndClasses(FileScopePtr fs) {
const StringToFunctionScopePtrMap &funcs = fs->getFunctions();
@@ -653,11 +586,6 @@ void AnalysisResult::collectFunctionsAndClasses(FileScopePtr fs) {
ClassScopePtrVec &clsVec = m_classDecs[iter->first];
clsVec.insert(clsVec.end(), iter->second.begin(), iter->second.end());
}
m_classAliases.insert(fs->getClassAliases().begin(),
fs->getClassAliases().end());
m_typeAliasNames.insert(fs->getTypeAliasNames().begin(),
fs->getTypeAliasNames().end());
}
static bool by_filename(const FileScopePtr &f1, const FileScopePtr &f2) {
@@ -683,8 +611,6 @@ void AnalysisResult::analyzeProgram(bool system /* = false */) {
// Keep generated code identical without randomness
canonicalizeSymbolOrder();
markRedeclaringClasses();
// Analyze some special cases
for (set<string>::const_iterator it = Option::VolatileClasses.begin();
it != Option::VolatileClasses.end(); ++it) {
@@ -695,7 +621,6 @@ void AnalysisResult::analyzeProgram(bool system /* = false */) {
}
checkClassDerivations();
resolveNSFallbackFuncs();
// Analyze All
Logger::Verbose("Analyzing All");
@@ -735,7 +660,7 @@ void AnalysisResult::analyzeProgram(bool system /* = false */) {
for (StringToFunctionScopePtrMap::const_iterator iterMethod =
methods.begin(); iterMethod != methods.end(); ++iterMethod) {
FunctionScopePtr func = iterMethod->second;
if (Option::WholeProgram && !func->hasImpl() && needAbstractMethodImpl) {
if (!func->hasImpl() && needAbstractMethodImpl) {
FunctionScopePtr tmpFunc =
cls->findFunction(ar, func->getName(), true, true);
always_assert(!tmpFunc || !tmpFunc->hasImpl());
@@ -854,14 +779,8 @@ void AnalysisResult::analyzeProgramFinal() {
for (uint i = 0; i < m_fileScopes.size(); i++) {
m_fileScopes[i]->analyzeProgram(ar);
}
// Keep generated code identical without randomness
canonicalizeSymbolOrder();
// XXX: this is only here because canonicalizeSymbolOrder used to do
// it---is it necessary to repeat at this phase? (Probably not ...)
markRedeclaringClasses();
setPhase(AnalysisResult::CodeGen);
}
@@ -934,11 +853,9 @@ struct OptVisitor {
OptVisitor(AnalysisResultPtr ar, unsigned nscope) :
m_ar(ar), m_nscope(nscope), m_dispatcher(0) {
}
/* implicit */ OptVisitor(const Visitor &po)
: m_ar(po.m_ar)
, m_nscope(po.m_nscope)
, m_dispatcher(po.m_dispatcher)
{
OptVisitor(const Visitor &po) : m_ar(po.m_ar),
m_nscope(po.m_nscope),
m_dispatcher(po.m_dispatcher) {
const_cast<Visitor&>(po).m_dispatcher = 0;
}
~OptVisitor() {
@@ -983,7 +900,7 @@ public:
virtual void doJob(BlockScope *scope) {
#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
++AnalysisResult::s_NumDoJobCalls;
atomic_inc(AnalysisResult::s_NumDoJobCalls);
ConcurrentBlockScopeRawPtrIntHashMap::accessor acc;
AnalysisResult::s_DoJobUniqueScopes.insert(acc,
BlockScopeRawPtr(scope));
@@ -1043,13 +960,13 @@ public:
break;
case BlockScope::MarkProcessing:
#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
++AnalysisResult::s_NumForceRerunGlobal;
atomic_inc(AnalysisResult::s_NumForceRerunGlobal);
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */
pf->first->setForceRerun(true);
break;
case BlockScope::MarkProcessed:
#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
++AnalysisResult::s_NumReactivateGlobal;
atomic_inc(AnalysisResult::s_NumReactivateGlobal);
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */
if (visitor->activateScope(pf->first)) {
visitor->enqueue(pf->first);
@@ -1085,7 +1002,7 @@ public:
int m = pf->first->getMark();
if (pf->second & useKinds && m == BlockScope::MarkProcessed) {
#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
++AnalysisResult::s_NumReactivateUseKinds;
atomic_inc(AnalysisResult::s_NumReactivateUseKinds);
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */
bool ready = visitor->activateScope(pf->first);
always_assert(!ready);
@@ -1109,7 +1026,7 @@ public:
// in its entirety. Thus, we must force it to run again in
// order to be able to observe all the updates.
#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
++AnalysisResult::s_NumForceRerunUseKinds;
atomic_inc(AnalysisResult::s_NumForceRerunUseKinds);
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */
always_assert(pf->first->getNumDepsToWaitFor() == 0);
pf->first->setForceRerun(true);
@@ -1154,12 +1071,12 @@ typedef OptWorker<Post> PostOptWorker;
template<>
void OptWorker<Pre>::onThreadEnter() {
hphp_session_init();
if (!Option::SystemGen) hphp_session_init();
}
template<>
void OptWorker<Pre>::onThreadExit() {
hphp_session_exit();
if (!Option::SystemGen) hphp_session_exit();
}
/**
@@ -1240,11 +1157,11 @@ AnalysisResult::postWaitCallback(bool first,
}
#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
std::atomic<int> AnalysisResult::s_NumDoJobCalls(0);
std::atomic<int> AnalysisResult::s_NumForceRerunGlobal(0);
std::atomic<int> AnalysisResult::s_NumReactivateGlobal(0);
std::atomic<int> AnalysisResult::s_NumForceRerunUseKinds(0);
std::atomic<int> AnalysisResult::s_NumReactivateUseKinds(0);
int AnalysisResult::s_NumDoJobCalls = 0;
int AnalysisResult::s_NumForceRerunGlobal = 0;
int AnalysisResult::s_NumReactivateGlobal = 0;
int AnalysisResult::s_NumForceRerunUseKinds = 0;
int AnalysisResult::s_NumReactivateUseKinds = 0;
ConcurrentBlockScopeRawPtrIntHashMap
AnalysisResult::s_DoJobUniqueScopes;
@@ -1519,7 +1436,7 @@ DepthFirstVisitor<InferTypes, OptVisitor>::visitScope(BlockScopeRawPtr scope) {
// there are potentially AST nodes which are interested in the updated
// return type
#ifdef HPHP_INSTRUMENT_TYPE_INF
++RescheduleException::s_NumForceRerunSelfCaller;
atomic_inc(RescheduleException::s_NumForceRerunSelfCaller);
#endif /* HPHP_INSTRUMENT_TYPE_INF */
scope->setForceRerun(true);
}
@@ -1536,7 +1453,7 @@ DepthFirstVisitor<InferTypes, OptVisitor>::visitScope(BlockScopeRawPtr scope) {
// potential deadlock detected- reschedule
// this scope to run at a later time
#ifdef HPHP_INSTRUMENT_TYPE_INF
++RescheduleException::s_NumReschedules;
atomic_inc(RescheduleException::s_NumReschedules);
#endif /* HPHP_INSTRUMENT_TYPE_INF */
ret |= scope->getUpdated();
if (m) {
@@ -1593,9 +1510,9 @@ bool AnalysisResult::postWaitCallback<InferTypes>(
}
#ifdef HPHP_INSTRUMENT_TYPE_INF
std::atomic<int> RescheduleException::s_NumReschedules(0);
std::atomic<int> RescheduleException::s_NumForceRerunSelfCaller(0);
std::atomic<int> RescheduleException::s_NumRetTypesChanged(0);
int RescheduleException::s_NumReschedules = 0;
int RescheduleException::s_NumForceRerunSelfCaller = 0;
int RescheduleException::s_NumRetTypesChanged = 0;
LProfileMap BaseTryLock::s_LockProfileMap;
#endif /* HPHP_INSTRUMENT_TYPE_INF */
+33 -67
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,19 +14,19 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ANALYSIS_RESULT_H_
#define incl_HPHP_ANALYSIS_RESULT_H_
#ifndef __ANALYSIS_RESULT_H__
#define __ANALYSIS_RESULT_H__
#include "hphp/compiler/code_generator.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/block_scope.h"
#include "hphp/compiler/analysis/symbol_table.h"
#include "hphp/compiler/analysis/function_container.h"
#include "hphp/compiler/package.h"
#include <compiler/code_generator.h>
#include <compiler/analysis/code_error.h>
#include <compiler/option.h>
#include <compiler/analysis/block_scope.h>
#include <compiler/analysis/symbol_table.h>
#include <compiler/analysis/function_container.h>
#include <compiler/package.h>
#include "hphp/util/string-bag.h"
#include "hphp/util/thread-local.h"
#include <util/string_bag.h>
#include <util/thread_local.h>
#include <boost/graph/adjacency_list.hpp>
#include <tbb/concurrent_hash_map.h>
@@ -91,12 +91,12 @@ public:
class Locker {
public:
explicit Locker(const AnalysisResult *ar) :
Locker(const AnalysisResult *ar) :
m_ar(const_cast<AnalysisResult*>(ar)),
m_mutex(m_ar->getMutex()) {
m_mutex.lock();
}
explicit Locker(AnalysisResultConstPtr ar) :
Locker(AnalysisResultConstPtr ar) :
m_ar(const_cast<AnalysisResult*>(ar.get())),
m_mutex(m_ar->getMutex()) {
m_mutex.lock();
@@ -148,8 +148,7 @@ public:
void addEntryPoint(const std::string &name);
void addEntryPoints(const std::vector<std::string> &names);
void addNSFallbackFunc(ConstructPtr c, FileScopePtr fs);
void loadBuiltinFunctions();
void loadBuiltins();
void analyzeProgram(bool system = false);
void analyzeIncludes();
@@ -237,22 +236,12 @@ public:
ClassScopePtr findClass(const std::string &className) const;
ClassScopePtr findClass(const std::string &className,
FindClassBy by);
/*
* Returns: whether the given name is the name of any type aliases
* in the whole program.
*/
bool isTypeAliasName(const std::string& name) const {
return m_typeAliasNames.count(name);
}
/**
* Find all the redeclared classes by the name, excluding system classes.
* Note that system classes cannot be redeclared.
*/
const ClassScopePtrVec &findRedeclaredClasses(
const std::string &className) const;
/**
* Find all the classes by the name, including system classes.
*/
@@ -307,12 +296,10 @@ public:
void addNamedScalarVarArray(const std::string &s);
StringToClassScopePtrVecMap getExtensionClasses();
void addInteger(int64_t n);
private:
Package *m_package;
bool m_parseOnDemand;
std::vector<std::string> m_parseOnDemandDirs;
std::set<std::pair<ConstructPtr, FileScopePtr> > m_nsFallbackFuncs;
Phase m_phase;
StringToFileScopePtrMap m_files;
FileScopePtrVec m_fileScopes;
@@ -328,13 +315,6 @@ private:
StringToFileScopePtrMap m_constDecs;
std::set<std::string> m_constRedeclared;
// Map names of class aliases to the class names they will alias.
// Only in WholeProgram mode. See markRedeclaringClasses.
std::multimap<std::string,std::string> m_classAliases;
// Names of type aliases.
std::set<std::string> m_typeAliasNames;
bool m_classForcedVariants[2];
StatementPtrVec m_stmts;
@@ -343,12 +323,12 @@ private:
std::string m_outputPath;
public:
AnalysisResultPtr shared_from_this() {
return static_pointer_cast<AnalysisResult>
return boost::static_pointer_cast<AnalysisResult>
(BlockScope::shared_from_this());
}
AnalysisResultConstPtr shared_from_this() const {
return static_pointer_cast<const AnalysisResult>
return boost::static_pointer_cast<const AnalysisResult>
(BlockScope::shared_from_this());
}
@@ -368,11 +348,6 @@ private:
*/
bool inParseOnDemandDirs(const std::string &filename) const;
/*
* Find the names of all functions and classes in the program; mark
* functions with duplicate names as redeclaring, but duplicate
* classes aren't yet marked. See markRedeclaringClasses.
*/
void collectFunctionsAndClasses(FileScopePtr fs);
/**
@@ -381,21 +356,12 @@ private:
*/
void canonicalizeSymbolOrder();
/*
* After all the class names have been collected and symbol order is
* canonicalized, this passes through and marks duplicate class
* names as redeclaring.
*/
void markRedeclaringClasses();
/**
* Checks circular class derivations that can cause stack overflows for
* subsequent analysis. Also checks to make sure no two redundant parents.
*/
void checkClassDerivations();
void resolveNSFallbackFuncs();
int getFileSize(FileScopePtr fs);
public:
@@ -404,12 +370,12 @@ public:
s_changedScopesMapThreadLocal);
#ifdef HPHP_INSTRUMENT_PROCESS_PARALLEL
static std::atomic<int> s_NumDoJobCalls;
static int s_NumDoJobCalls;
static ConcurrentBlockScopeRawPtrIntHashMap s_DoJobUniqueScopes;
static std::atomic<int> s_NumForceRerunGlobal;
static std::atomic<int> s_NumReactivateGlobal;
static std::atomic<int> s_NumForceRerunUseKinds;
static std::atomic<int> s_NumReactivateUseKinds;
static int s_NumForceRerunGlobal;
static int s_NumReactivateGlobal;
static int s_NumForceRerunUseKinds;
static int s_NumReactivateUseKinds;
#endif /* HPHP_INSTRUMENT_PROCESS_PARALLEL */
private:
@@ -433,13 +399,13 @@ private:
class RescheduleException : public Exception {
public:
explicit RescheduleException(BlockScopeRawPtr scope) :
RescheduleException(BlockScopeRawPtr scope) :
Exception(), m_scope(scope) {}
BlockScopeRawPtr &getScope() { return m_scope; }
#ifdef HPHP_INSTRUMENT_TYPE_INF
static std::atomic<int> s_NumReschedules;
static std::atomic<int> s_NumForceRerunSelfCaller;
static std::atomic<int> s_NumRetTypesChanged;
static int s_NumReschedules;
static int s_NumForceRerunSelfCaller;
static int s_NumRetTypesChanged;
#endif /* HPHP_INSTRUMENT_TYPE_INF */
private:
BlockScopeRawPtr m_scope;
@@ -447,7 +413,7 @@ private:
class SetCurrentScope {
public:
explicit SetCurrentScope(BlockScopeRawPtr scope) {
SetCurrentScope(BlockScopeRawPtr scope) {
assert(!((*AnalysisResult::s_currentScopeThreadLocal).get()));
*AnalysisResult::s_currentScopeThreadLocal = scope;
scope->setInVisitScopes(true);
@@ -533,9 +499,9 @@ private:
}
}
#else
explicit BaseTryLock(BlockScopeRawPtr scopeToLock,
bool lockCondition = true,
bool profile = true)
BaseTryLock(BlockScopeRawPtr scopeToLock,
bool lockCondition = true,
bool profile = true)
: m_profiler(profile),
m_mutex(scopeToLock->getInferTypesMutex()),
m_acquired(false) {
@@ -570,8 +536,8 @@ public:
bool profile = true) :
BaseTryLock(scopeToLock, fromFunction, fromLine, true, profile) {}
#else
explicit TryLock(BlockScopeRawPtr scopeToLock,
bool profile = true) :
TryLock(BlockScopeRawPtr scopeToLock,
bool profile = true) :
BaseTryLock(scopeToLock, true, profile) {}
#endif /* HPHP_INSTRUMENT_TYPE_INF */
};
@@ -629,4 +595,4 @@ public:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ANALYSIS_RESULT_H_
#endif // __ANALYSIS_RESULT_H__
+6 -6
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,8 +14,8 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/ast_walker.h"
#include "hphp/compiler/statement/statement.h"
#include <compiler/analysis/ast_walker.h>
#include <compiler/statement/statement.h>
using namespace HPHP;
@@ -23,17 +23,17 @@ using namespace HPHP;
bool FunctionWalker::SkipRecurse(ConstructPtr cp) {
StatementPtr s(
dynamic_pointer_cast<Statement>(cp));
boost::dynamic_pointer_cast<Statement>(cp));
return SkipRecurse(s);
}
bool FunctionWalker::SkipRecurse(ConstructConstPtr cp) {
StatementConstPtr s(
dynamic_pointer_cast<const Statement>(cp));
boost::dynamic_pointer_cast<const Statement>(cp));
return SkipRecurse(s);
}
bool FunctionWalker::SkipRecurse(ConstructRawPtr cp) {
StatementRawPtr s(
dynamic_pointer_cast<Statement>(cp));
boost::dynamic_pointer_cast<Statement>(cp));
return SkipRecurse(s);
}
+8 -8
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_AST_WALKER_H_
#define incl_HPHP_AST_WALKER_H_
#ifndef __AST_WALKER_H__
#define __AST_WALKER_H__
#include "hphp/compiler/hphp.h"
#include "hphp/compiler/construct.h"
#include <compiler/hphp.h>
#include <compiler/construct.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -26,7 +26,7 @@ namespace HPHP {
class AstWalkerState {
public:
AstWalkerState() : index(0) {}
explicit AstWalkerState(ConstructRawPtr c) : cp(c), index(0) {}
AstWalkerState(ConstructRawPtr c) : cp(c), index(0) {}
friend bool operator==(const AstWalkerState &s1,
const AstWalkerState &s2) {
@@ -40,7 +40,7 @@ public:
class AstWalkerStateVec : public std::vector<AstWalkerState> {
public:
AstWalkerStateVec() {}
explicit AstWalkerStateVec(ConstructRawPtr cp) {
AstWalkerStateVec(ConstructRawPtr cp) {
push_back(AstWalkerState(cp));
}
};
@@ -132,4 +132,4 @@ public:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_AST_WALKER_H_
#endif // __AST_WALKER_H__
+3 -3
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -15,8 +15,8 @@
*/
#include <stdlib.h>
#include "hphp/compiler/analysis/bit_set_vec.h"
#include "hphp/compiler/analysis/data_flow.h"
#include <compiler/analysis/bit_set_vec.h>
#include <compiler/analysis/data_flow.h>
using namespace HPHP;
+2 -2
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -19,7 +19,7 @@
#include <limits.h>
#include <stddef.h>
#include "hphp/util/assertions.h"
#include "util/assertions.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
+14 -31
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,17 +14,16 @@
+----------------------------------------------------------------------+
*/
#include <compiler/expression/expression.h>
#include "hphp/compiler/analysis/block_scope.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/file_scope.h"
#include <compiler/analysis/block_scope.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/statement/statement_list.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/constant_table.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/file_scope.h>
using namespace HPHP;
@@ -90,29 +89,13 @@ AnalysisResultRawPtr BlockScope::getContainingProgram() {
return AnalysisResultRawPtr((AnalysisResult*)bs);
}
FunctionScopeRawPtr BlockScope::getContainingNonClosureFunction() {
BlockScope *bs = this;
// walk out through all the closures
while (bs && bs->is(BlockScope::FunctionScope)) {
HPHP::FunctionScope *fs = static_cast<HPHP::FunctionScope*>(bs);
if (!fs->isClosure()) {
return FunctionScopeRawPtr(fs);
}
bs = bs->m_outerScope.get();
}
return FunctionScopeRawPtr();
}
ClassScopeRawPtr BlockScope::getContainingClass() {
BlockScope *bs = getContainingNonClosureFunction().get();
if (!bs) {
bs = this;
}
if (bs && bs->is(BlockScope::FunctionScope)) {
BlockScope *bs = this;
if (bs->is(BlockScope::FunctionScope)) {
bs = bs->m_outerScope.get();
}
if (!bs || !bs->is(BlockScope::ClassScope)) {
return ClassScopeRawPtr();
if (bs && !bs->is(BlockScope::ClassScope)) {
bs = 0;
}
return ClassScopeRawPtr((HPHP::ClassScope*)bs);
}
+9 -10
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,14 +14,14 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_BLOCK_SCOPE_H_
#define incl_HPHP_BLOCK_SCOPE_H_
#ifndef __BLOCK_SCOPE_H__
#define __BLOCK_SCOPE_H__
#include "hphp/compiler/hphp.h"
#include <compiler/hphp.h>
#include "hphp/util/bits.h"
#include "hphp/util/lock.h"
#include "hphp/runtime/base/macros.h"
#include <util/bits.h>
#include <util/lock.h>
#include <runtime/base/macros.h>
#include <tbb/concurrent_hash_map.h>
@@ -66,7 +66,7 @@ typedef SimpleMutex InferTypesMutex;
* Base class of ClassScope and FunctionScope.
*/
class BlockScope : private boost::noncopyable,
public std::enable_shared_from_this<BlockScope> {
public boost::enable_shared_from_this<BlockScope> {
public:
enum KindOf {
ClassScope,
@@ -178,7 +178,6 @@ public:
VariableTablePtr getVariables() { return m_variables;}
ConstantTablePtr getConstants() { return m_constants;}
ClassScopeRawPtr getContainingClass();
FunctionScopeRawPtr getContainingNonClosureFunction();
FunctionScopeRawPtr getContainingFunction() const {
return FunctionScopeRawPtr(is(FunctionScope) ?
(HPHP::FunctionScope*)this : 0);
@@ -366,4 +365,4 @@ public:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_BLOCK_SCOPE_H_
#endif // __BLOCK_SCOPE_H__
+172 -44
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,38 +14,37 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/construct.h"
#include "hphp/compiler/expression/class_constant_expression.h"
#include "hphp/compiler/expression/closure_expression.h"
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/compiler/statement/interface_statement.h"
#include "hphp/compiler/statement/function_statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/runtime/base/builtin-functions.h"
#include "hphp/runtime/base/class-info.h"
#include "hphp/compiler/statement/class_variable.h"
#include "hphp/compiler/statement/class_constant.h"
#include "hphp/compiler/statement/use_trait_statement.h"
#include "hphp/compiler/statement/trait_prec_statement.h"
#include "hphp/compiler/statement/trait_alias_statement.h"
#include "hphp/runtime/base/zend-string.h"
#include "hphp/util/util.h"
#include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/constant_table.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/construct.h>
#include <compiler/expression/class_constant_expression.h>
#include <compiler/expression/closure_expression.h>
#include <compiler/expression/constant_expression.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/unary_op_expression.h>
#include <compiler/expression/simple_function_call.h>
#include <compiler/option.h>
#include <compiler/parser/parser.h>
#include <compiler/statement/interface_statement.h>
#include <compiler/statement/function_statement.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/statement_list.h>
#include <runtime/base/builtin_functions.h>
#include <runtime/base/class_info.h>
#include <compiler/statement/class_variable.h>
#include <compiler/statement/class_constant.h>
#include <compiler/statement/use_trait_statement.h>
#include <compiler/statement/trait_prec_statement.h>
#include <compiler/statement/trait_alias_statement.h>
#include <runtime/base/zend/zend_string.h>
#include <util/util.h>
using namespace HPHP;
using std::map;
@@ -62,7 +61,8 @@ ClassScope::ClassScope(KindOf kindOf, const std::string &name,
m_kindOf(kindOf), m_derivesFromRedeclaring(FromNormal),
m_traitStatus(NOT_FLATTENED), m_volatile(false),
m_persistent(false), m_derivedByDynamic(false),
m_needsCppCtor(false), m_needsInit(true), m_knownBases(0) {
m_sep(false), m_needsCppCtor(false), m_needsInit(true), m_knownBases(0),
m_needsEnableDestructor(0) {
m_dynamic = Option::IsDynamicClass(m_name);
@@ -92,8 +92,8 @@ ClassScope::ClassScope(AnalysisResultPtr ar,
m_kindOf(KindOfObjectClass), m_derivesFromRedeclaring(FromNormal),
m_traitStatus(NOT_FLATTENED), m_dynamic(false),
m_volatile(false), m_persistent(false),
m_derivedByDynamic(false), m_needsCppCtor(false),
m_needsInit(true), m_knownBases(0) {
m_derivedByDynamic(false), m_sep(false), m_needsCppCtor(false),
m_needsInit(true), m_knownBases(0), m_needsEnableDestructor(0) {
BOOST_FOREACH(FunctionScopePtr f, methods) {
if (f->getName() == "__construct") setAttribute(HasConstructor);
else if (f->getName() == "__destruct") setAttribute(HasDestructor);
@@ -356,7 +356,7 @@ void ClassScope::collectMethods(AnalysisResultPtr ar,
setVolatile();
}
}
} else {
} else if (!Option::SystemGen) {
Compiler::Error(Compiler::UnknownBaseClass, m_stmt, base);
if (base == m_parent) {
ar->declareUnknownClass(m_parent);
@@ -403,12 +403,23 @@ MethodStatementPtr
ClassScope::importTraitMethod(const TraitMethod& traitMethod,
AnalysisResultPtr ar,
string methName,
GeneratorRenameMap& genRenameMap,
const std::map<string, MethodStatementPtr>&
importedTraitMethods) {
MethodStatementPtr meth = traitMethod.m_method;
string origMethName = traitMethod.m_originalName;
ModifierExpressionPtr modifiers = traitMethod.m_modifiers;
if (meth->getOrigGeneratorFunc()) {
const string &name = meth->getOrigGeneratorFunc()->getName();
if (!importedTraitMethods.count(name)) {
// Dont import the generator, if the origGenerator wasnt imported
// this happens when a generator in the trait is hidden by a non-generator
// method in the importing class.
return MethodStatementPtr();
}
}
MethodStatementPtr cloneMeth = dynamic_pointer_cast<MethodStatement>(
dynamic_pointer_cast<ClassStatement>(m_stmt)->addClone(meth));
cloneMeth->setName(methName);
@@ -423,9 +434,17 @@ ClassScope::importTraitMethod(const TraitMethod& traitMethod,
ClassScopePtr cScope = dynamic_pointer_cast<ClassScope>(shared_from_this());
cloneMeth->fixupSelfAndParentTypehints( cScope );
// Generator methods need to be renamed, otherwise code gen produces multiple
// continuation classes with the same name
if (funcScope->isGenerator()) {
const string& newName = getNewGeneratorName(funcScope, genRenameMap);
methName = origMethName = newName;
cloneMeth->setName(newName);
cloneMeth->setOriginalName(newName);
}
FunctionScopePtr cloneFuncScope
(new HPHP::FunctionScope(funcScope, ar, methName, origMethName, cloneMeth,
cloneMeth->getModifiers(), cScope->isUserClass()));
cloneMeth->getModifiers()));
cloneMeth->resetScope(cloneFuncScope, true);
cloneFuncScope->setOuterScope(shared_from_this());
informClosuresAboutScopeClone(cloneMeth, cloneFuncScope, ar);
@@ -433,10 +452,6 @@ ClassScope::importTraitMethod(const TraitMethod& traitMethod,
cloneMeth->addTraitMethodToScope(ar,
dynamic_pointer_cast<ClassScope>(shared_from_this()));
// Preserve original filename (as this varies per-function and not per-unit
// in the case of methods imported from flattened traits)
cloneMeth->setOriginalFilename(meth->getFileScope()->getName());
return cloneMeth;
}
@@ -731,6 +746,84 @@ void ClassScope::removeSpareTraitAbstractMethods(AnalysisResultPtr ar) {
}
}
const string& ClassScope::getNewGeneratorName(
FunctionScopePtr genFuncScope, GeneratorRenameMap &genRenameMap) {
assert(genFuncScope->isGenerator());
const string& oldName = genFuncScope->getName();
GeneratorRenameMap::iterator mapIt = genRenameMap.find(oldName);
if (mapIt != genRenameMap.end()) {
return mapIt->second;
}
string newName = oldName + "_" +
lexical_cast<string>(genFuncScope->getNewID());
genRenameMap[oldName] = newName;
return genRenameMap[oldName];
}
void
ClassScope::renameCreateContinuationCalls(AnalysisResultPtr ar,
ConstructPtr c,
ImportedMethodMap &importedMethods) {
if (!c) return;
SimpleFunctionCallPtr funcCall = dynamic_pointer_cast<SimpleFunctionCall>(c);
if (funcCall && funcCall->getName() == "hphp_create_continuation") {
ExpressionListPtr params = funcCall->getParams();
assert(params->getCount() >= 2);
const string &oldClassName =
dynamic_pointer_cast<ScalarExpression>((*params)[0])->getString();
ClassScopePtr oldClassScope = ar->findClass(oldClassName);
if (!oldClassScope || !oldClassScope->isTrait()) return;
const string &oldGenName =
dynamic_pointer_cast<ScalarExpression>((*params)[1])->getString();
MethodStatementPtr origGenStmt = importedMethods[oldGenName];
assert(origGenStmt);
const string &newGenName = origGenStmt->getOriginalName();
ExpressionPtr newGenExpr = funcCall->makeScalarExpression(ar, newGenName);
ExpressionPtr newClsExpr = funcCall->makeScalarExpression(ar, getName());
(*params)[0] = newClsExpr;
(*params)[1] = newGenExpr;
funcCall->analyzeProgram(ar);
return;
}
for (int i=0; i < c->getKidCount(); i++) {
renameCreateContinuationCalls(ar, c->getNthKid(i), importedMethods);
}
}
void ClassScope::relinkGeneratorMethods(
AnalysisResultPtr ar,
ImportedMethodMap &importedMethods) {
for (ImportedMethodMap::const_iterator methIt =
importedMethods.begin(); methIt != importedMethods.end(); methIt++) {
MethodStatementPtr newMeth = methIt->second;
// Skip non-generator methods
if (!newMeth) continue;
if (newMeth->getOrigGeneratorFunc()) {
// Get corresponding original generator method in the current class
const string& origGenName = newMeth->getOrigGeneratorFunc()->getName();
MethodStatementPtr origGenStmt = importedMethods[origGenName];
assert(origGenStmt);
// It must be an orig gen func already, we're just updating to point
// to the corresponding method cloned from the trait
assert(origGenStmt->getGeneratorFunc());
newMeth->setOrigGeneratorFunc(origGenStmt);
origGenStmt->setGeneratorFunc(newMeth);
}
// OrigGenerator methods need to have their hphp_create_continuation calls
// patched to the new generator name.
if (newMeth->getGeneratorFunc()) {
renameCreateContinuationCalls(ar, newMeth, importedMethods);
}
}
}
void ClassScope::importUsedTraits(AnalysisResultPtr ar) {
if (m_traitStatus == FLATTENED) return;
if (m_traitStatus == BEING_FLATTENED) {
@@ -784,6 +877,8 @@ void ClassScope::importUsedTraits(AnalysisResultPtr ar) {
std::map<string, MethodStatementPtr> importedTraitMethods;
std::vector<std::pair<string,const TraitMethod*> > importedTraitsWithOrigName;
GeneratorRenameMap genRenameMap;
// Actually import the methods
for (MethodToTraitListMap::const_iterator
iter = m_importMethToTraitMap.begin();
@@ -828,12 +923,15 @@ void ClassScope::importUsedTraits(AnalysisResultPtr ar) {
const TraitMethod *traitMethod = importedTraitsWithOrigName[i].second;
MethodStatementPtr newMeth = importTraitMethod(
*traitMethod, ar, Util::toLower(traitMethod->m_originalName),
importedTraitMethods);
genRenameMap, importedTraitMethods);
if (newMeth) {
importedTraitMethods[sourceName] = newMeth;
}
}
// Relink generator and origGenerator methods
relinkGeneratorMethods(ar, importedTraitMethods);
// Import trait properties
importTraitProperties(ar);
@@ -1095,10 +1193,10 @@ void ClassScope::getAllParents(AnalysisResultConstPtr ar,
std::vector<std::string> &names) {
if (m_stmt) {
if (isInterface()) {
dynamic_pointer_cast<InterfaceStatement>
boost::dynamic_pointer_cast<InterfaceStatement>
(m_stmt)->getAllParents(ar, names);
} else {
dynamic_pointer_cast<ClassStatement>
boost::dynamic_pointer_cast<ClassStatement>
(m_stmt)->getAllParents(ar, names);
}
} else {
@@ -1229,7 +1327,7 @@ void ClassScope::serialize(JSON::DocTarget::OutputStream &out) const {
ms.add("parent");
if (m_parent.empty()) {
out << JSON::Null();
out << JSON::Null;
} else {
out << GetDocName(out.analysisResult(), self, m_parent);
}
@@ -1333,6 +1431,36 @@ bool ClassScope::addFunction(AnalysisResultConstPtr ar,
return true;
}
/*
* A class without a constructor, but with a destructor may need a special
* create method to clear the NoDestructor flag - but only if
* there is a constructor somewhere above us, and if /that/ constructor
* doesnt need to clear the NoDestructor flag.
*/
bool ClassScope::needsEnableDestructor(
AnalysisResultConstPtr ar) const {
if (m_needsEnableDestructor & 2) {
return m_needsEnableDestructor & 1;
}
bool ret =
(!derivesFromRedeclaring() &&
!getAttribute(HasConstructor) &&
!getAttribute(ClassNameConstructor));
if (ret) {
if (!getAttribute(HasDestructor) && !m_parent.empty()) {
if (ClassScopePtr parent = getParentScope(ar)) {
if (!parent->needsEnableDestructor(ar)) {
ret = false;
}
}
}
}
m_needsEnableDestructor = ret ? 3 : 2;
return ret;
}
bool ClassScope::canSkipCreateMethod(AnalysisResultConstPtr ar) const {
// create() is not necessary if
// 1) not inheriting from any class
+32 -14
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,19 +14,19 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CLASS_SCOPE_H_
#define incl_HPHP_CLASS_SCOPE_H_
#ifndef __CLASS_SCOPE_H__
#define __CLASS_SCOPE_H__
#include "hphp/compiler/analysis/block_scope.h"
#include "hphp/compiler/analysis/function_container.h"
#include "hphp/compiler/statement/class_statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/trait_prec_statement.h"
#include "hphp/compiler/statement/trait_alias_statement.h"
#include "hphp/compiler/expression/user_attribute.h"
#include "hphp/util/json.h"
#include "hphp/util/case-insensitive.h"
#include "hphp/compiler/option.h"
#include <compiler/analysis/block_scope.h>
#include <compiler/analysis/function_container.h>
#include <compiler/statement/class_statement.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/trait_prec_statement.h>
#include <compiler/statement/trait_alias_statement.h>
#include <compiler/expression/user_attribute.h>
#include <util/json.h>
#include <util/case_insensitive.h>
#include <compiler/option.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -169,6 +169,10 @@ public:
return m_derivedByDynamic;
}
/* Whether this class is brought in by a separable extension */
void setSepExtension() { m_sep = true;}
bool isSepExtension() const { return m_sep;}
/**
* Get/set attributes.
*/
@@ -366,6 +370,7 @@ public:
return m_needsInit;
}
bool needsEnableDestructor(AnalysisResultConstPtr ar) const;
bool canSkipCreateMethod(AnalysisResultConstPtr ar) const;
bool checkHasPropTable(AnalysisResultConstPtr ar);
@@ -403,6 +408,7 @@ private:
typedef std::list<TraitMethod> TraitMethodList;
typedef std::map<std::string, TraitMethodList> MethodToTraitListMap;
typedef std::map<std::string, std::string> GeneratorRenameMap;
MethodToTraitListMap m_importMethToTraitMap;
typedef std::map<std::string, MethodStatementPtr> ImportedMethodMap;
@@ -419,6 +425,7 @@ private:
unsigned m_volatile:1; // for class_exists
unsigned m_persistent:1;
unsigned m_derivedByDynamic:1;
unsigned m_sep:1;
unsigned m_needsCppCtor:1;
unsigned m_needsInit:1;
// m_knownBases has a bit for each base class saying whether
@@ -426,6 +433,7 @@ private:
// for classes with more than 31 bases, bit 31 is set iff
// bases 32 through n are all known.
unsigned m_knownBases;
mutable unsigned m_needsEnableDestructor:2;
void addImportTraitMethod(const TraitMethod &traitMethod,
const std::string &methName);
@@ -440,11 +448,15 @@ private:
MethodStatementPtr importTraitMethod(const TraitMethod& traitMethod,
AnalysisResultPtr ar,
std::string methName,
GeneratorRenameMap& genRenameMap,
const ImportedMethodMap &
importedTraitMethods);
void importTraitProperties(AnalysisResultPtr ar);
void relinkGeneratorMethods(AnalysisResultPtr ar,
ImportedMethodMap& importedMethods);
void findTraitMethodsToImport(AnalysisResultPtr ar, ClassScopePtr trait);
MethodStatementPtr findTraitMethod(AnalysisResultPtr ar,
@@ -467,8 +479,14 @@ private:
bool hasMethod(const std::string &methodName) const;
const std::string& getNewGeneratorName(FunctionScopePtr genFuncScope,
GeneratorRenameMap& genRenameMap);
void renameCreateContinuationCalls(AnalysisResultPtr ar, ConstructPtr c,
ImportedMethodMap &importedMethods);
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CLASS_SCOPE_H_
#endif // __CLASS_SCOPE_H__
+9 -9
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,13 +14,13 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/compiler/construct.h"
#include "hphp/compiler/option.h"
#include "hphp/util/exception.h"
#include "hphp/util/lock.h"
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/parser/parser.h>
#include <compiler/construct.h>
#include <compiler/option.h>
#include <util/exception.h>
#include <util/lock.h>
using namespace HPHP::JSON;
@@ -79,7 +79,7 @@ std::vector<const char *> &CodeErrors::getErrorTexts() {
if (ErrorTexts.empty()) {
ErrorTexts.resize(ErrorCount);
#define CODE_ERROR_ENTRY(x) ErrorTexts[x] = #x;
#include "hphp/compiler/analysis/core_code_error.inc"
#include "compiler/analysis/core_code_error.inc"
#undef CODE_ERROR_ENTRY
}
return ErrorTexts;
+7 -7
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_COMPILER_ERROR_H_
#define incl_HPHP_COMPILER_ERROR_H_
#ifndef __COMPILER_ERROR_H__
#define __COMPILER_ERROR_H__
#include "hphp/compiler/analysis/type.h"
#include "hphp/util/json.h"
#include <compiler/analysis/type.h>
#include <util/json.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -31,7 +31,7 @@ namespace Compiler {
enum ErrorType {
#define CODE_ERROR_ENTRY(x) x,
#include "hphp/compiler/analysis/core_code_error.inc"
#include "compiler/analysis/core_code_error.inc"
#undef CODE_ERROR_ENTRY
ErrorCount,
NoError
@@ -79,4 +79,4 @@ bool HasError(); // any error
///////////////////////////////////////////////////////////////////////////////
}}
#endif // incl_HPHP_COMPILER_ERROR_H_
#endif // __COMPILER_ERROR_H__
+13 -13
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,18 +14,18 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/type.h"
#include "hphp/compiler/code_generator.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/option.h"
#include "hphp/util/util.h"
#include "hphp/util/hash.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/runtime/base/complex-types.h"
#include <compiler/analysis/constant_table.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/type.h>
#include <compiler/code_generator.h>
#include <compiler/expression/expression.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/option.h>
#include <util/util.h>
#include <util/hash.h>
#include <compiler/analysis/class_scope.h>
#include <runtime/base/complex_types.h>
using namespace HPHP;
+7 -7
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CONSTANT_TABLE_H_
#define incl_HPHP_CONSTANT_TABLE_H_
#ifndef __CONSTANT_TABLE_H__
#define __CONSTANT_TABLE_H__
#include "hphp/compiler/analysis/symbol_table.h"
#include "hphp/compiler/analysis/block_scope.h"
#include <compiler/analysis/symbol_table.h>
#include <compiler/analysis/block_scope.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -37,7 +37,7 @@ DECLARE_BOOST_TYPES(ClassScope);
*/
class ConstantTable : public SymbolTable {
public:
explicit ConstantTable(BlockScope &blockScope);
ConstantTable(BlockScope &blockScope);
/**
* Whether defining something to be non-scalar value or redeclared, or
@@ -103,4 +103,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CONSTANT_TABLE_H_
#endif // __CONSTANT_TABLE_H__
+92 -107
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -13,32 +13,32 @@
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/control_flow.h"
#include "compiler/analysis/ast_walker.h"
#include "compiler/analysis/control_flow.h"
#include "compiler/analysis/data_flow.h"
#include "compiler/expression/expression.h"
#include "compiler/expression/binary_op_expression.h"
#include "compiler/expression/unary_op_expression.h"
#include "compiler/expression/qop_expression.h"
#include "compiler/statement/statement.h"
#include "compiler/statement/method_statement.h"
#include "compiler/statement/statement_list.h"
#include "compiler/statement/if_branch_statement.h"
#include "compiler/statement/for_statement.h"
#include "compiler/statement/while_statement.h"
#include "compiler/statement/do_statement.h"
#include "compiler/statement/foreach_statement.h"
#include "compiler/statement/switch_statement.h"
#include "compiler/statement/break_statement.h"
#include "compiler/statement/try_statement.h"
#include "compiler/statement/finally_statement.h"
#include "compiler/statement/label_statement.h"
#include "compiler/statement/goto_statement.h"
#include "compiler/statement/case_statement.h"
#include <boost/graph/depth_first_search.hpp>
#include "hphp/compiler/analysis/ast_walker.h"
#include "hphp/compiler/analysis/data_flow.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/binary_op_expression.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/compiler/expression/qop_expression.h"
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/statement/if_branch_statement.h"
#include "hphp/compiler/statement/for_statement.h"
#include "hphp/compiler/statement/while_statement.h"
#include "hphp/compiler/statement/do_statement.h"
#include "hphp/compiler/statement/foreach_statement.h"
#include "hphp/compiler/statement/switch_statement.h"
#include "hphp/compiler/statement/break_statement.h"
#include "hphp/compiler/statement/try_statement.h"
#include "hphp/compiler/statement/finally_statement.h"
#include "hphp/compiler/statement/label_statement.h"
#include "hphp/compiler/statement/goto_statement.h"
#include "hphp/compiler/statement/case_statement.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -64,8 +64,8 @@ typedef hphp_hash_map<ConstructRawPtr, ControlBlock*,
class ControlFlowBuilder : public FunctionWalker {
public:
explicit ControlFlowBuilder(ControlFlowGraph *g) :
m_graph(g), m_pass(0), m_cur(0), m_head(0) {}
ControlFlowBuilder(ControlFlowGraph *g, bool isGenerator) :
m_graph(g), m_pass(0), m_isGenerator(isGenerator), m_cur(0), m_head(0) {}
int before(ConstructRawPtr cp);
int after(ConstructRawPtr cp);
@@ -161,6 +161,7 @@ private:
ControlFlowGraph *m_graph;
AstWalkerStateVec m_state;
int m_pass;
bool m_isGenerator;
ControlBlock *m_cur;
ControlBlock *m_head;
@@ -181,7 +182,7 @@ public:
class dfs_dump : public boost::default_dfs_visitor {
public:
explicit dfs_dump(AnalysisResultConstPtr ar) : m_ar(ar) {}
dfs_dump(AnalysisResultConstPtr ar) : m_ar(ar) {}
void discover_vertex(ControlFlowGraph::vertex_descriptor u,
const ControlFlowGraph &g) {
@@ -328,10 +329,9 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) {
}
case Statement::KindOfForStatement: {
ForStatementPtr fs(static_pointer_cast<ForStatement>(s));
ConstructRawPtr body(fs->getBody());
ConstructRawPtr cond(fs->getCondExp());
ConstructRawPtr incr(fs->getIncExp());
ConstructRawPtr cond(s->getNthKid(ForStatement::CondExpr));
ConstructRawPtr body(s->getNthKid(ForStatement::BodyStmt));
ConstructRawPtr incr(s->getNthKid(ForStatement::IncExpr));
if (cond) addEdge(cond, AfterConstruct, s, AfterConstruct);
ConstructRawPtr end = incr ? incr : body ? body : cond;
ConstructRawPtr start = cond ? cond : body ? body : incr;
@@ -341,9 +341,8 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) {
}
case Statement::KindOfWhileStatement: {
WhileStatementPtr ws(static_pointer_cast<WhileStatement>(s));
ConstructRawPtr body(ws->getBody());
ConstructRawPtr cond(ws->getCondExp());
ConstructRawPtr cond(s->getNthKid(WhileStatement::CondExpr));
ConstructRawPtr body(s->getNthKid(WhileStatement::BodyStmt));
addEdge(cond, AfterConstruct, s, AfterConstruct);
addEdge(body ? body : cond, AfterConstruct, cond, BeforeConstruct);
noFallThrough(s);
@@ -351,16 +350,15 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) {
}
case Statement::KindOfDoStatement: {
DoStatementPtr ds(static_pointer_cast<DoStatement>(s));
addEdge(ds->getCondExp(), AfterConstruct, s, BeforeConstruct);
ConstructRawPtr cond(s->getNthKid(DoStatement::CondExpr));
addEdge(cond, AfterConstruct, s, BeforeConstruct);
break;
}
case Statement::KindOfForEachStatement: {
ForEachStatementPtr fs(static_pointer_cast<ForEachStatement>(s));
ConstructRawPtr body(fs->getBody());
ConstructRawPtr name(fs->getNameExp());
ConstructRawPtr value(fs->getValueExp());
ConstructRawPtr body(s->getNthKid(ForEachStatement::BodyStmt));
ConstructRawPtr name(s->getNthKid(ForEachStatement::NameExpr));
ConstructRawPtr value(s->getNthKid(ForEachStatement::ValueExpr));
ConstructRawPtr begin = name ? name : value;
ConstructRawPtr end = body ? body : value;
addEdge(end, AfterConstruct, begin, BeforeConstruct);
@@ -416,7 +414,7 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) {
case Statement::KindOfReturnStatement: {
setEdge(s, AfterConstruct, root(), AfterConstruct);
noFallThrough(s);
if (!m_isGenerator) noFallThrough(s);
/*
* Since almost anything in php /might/ throw, we
* approximate, and add edges from the beginning and
@@ -452,31 +450,23 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) {
} else {
ConstructRawPtr kid;
switch (l->getKindOf()) {
case Statement::KindOfForEachStatement: {
ForEachStatementPtr fs(static_pointer_cast<ForEachStatement>(l));
kid = fs->getNameExp();
case Statement::KindOfForEachStatement:
kid = l->getNthKid(ForEachStatement::NameExpr);
if (!kid) {
kid = fs->getValueExp();
kid = l->getNthKid(ForEachStatement::ValueExpr);
}
break;
}
case Statement::KindOfForStatement: {
ForStatementPtr fs(static_pointer_cast<ForStatement>(l));
kid = fs->getIncExp();
if (!kid) kid = fs->getCondExp();
if (!kid) kid = fs->getBody();
case Statement::KindOfForStatement:
kid = l->getNthKid(ForStatement::IncExpr);
if (!kid) kid = l->getNthKid(ForStatement::CondExpr);
if (!kid) kid = l->getNthKid(ForStatement::BodyStmt);
break;
}
case Statement::KindOfWhileStatement: {
WhileStatementPtr ws(static_pointer_cast<WhileStatement>(l));
kid = ws->getCondExp();
case Statement::KindOfWhileStatement:
kid = l->getNthKid(WhileStatement::CondExpr);
break;
}
case Statement::KindOfDoStatement: {
DoStatementPtr ds(static_pointer_cast<DoStatement>(l));
kid = ds->getCondExp();
case Statement::KindOfDoStatement:
kid = l->getNthKid(DoStatement::CondExpr);
break;
}
default:
always_assert(0);
}
@@ -497,7 +487,6 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) {
}
case Statement::KindOfEchoStatement:
case Statement::KindOfTypedefStatement:
break;
default:
@@ -506,36 +495,36 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) {
} else {
ExpressionPtr e(dynamic_pointer_cast<Expression>(cp));
switch (e->getKindOf()) {
case Expression::KindOfBinaryOpExpression: {
BinaryOpExpressionPtr b(static_pointer_cast<BinaryOpExpression>(e));
if (b->isShortCircuitOperator()) {
ConstructPtr trueBranch, falseBranch;
ConstructLocation tLoc, fLoc;
getTrueFalseBranches(0, trueBranch, tLoc, falseBranch, fLoc);
assert(trueBranch);
assert(falseBranch);
if (b->isLogicalOrOperator()) {
addEdge(b->getExp1(), AfterConstruct, trueBranch, tLoc);
} else {
addEdge(b->getExp1(), AfterConstruct, falseBranch, fLoc);
case Expression::KindOfBinaryOpExpression:
{
BinaryOpExpressionPtr b(
static_pointer_cast<BinaryOpExpression>(e));
if (b->isShortCircuitOperator()) {
ConstructPtr trueBranch, falseBranch;
ConstructLocation tLoc, fLoc;
getTrueFalseBranches(0, trueBranch, tLoc, falseBranch, fLoc);
assert(trueBranch);
assert(falseBranch);
if (b->isLogicalOrOperator()) {
addEdge(e->getNthExpr(0), AfterConstruct, trueBranch, tLoc);
} else {
addEdge(e->getNthExpr(0), AfterConstruct, falseBranch, fLoc);
}
}
}
break;
}
case Expression::KindOfQOpExpression: {
QOpExpressionPtr q(static_pointer_cast<QOpExpression>(e));
if (ExpressionPtr e1 = q->getYes()) {
addEdge(q->getCondition(), AfterConstruct,
q->getNo(), BeforeConstruct);
case Expression::KindOfQOpExpression:
if (ExpressionPtr e1 = e->getNthExpr(1)) {
addEdge(e->getNthExpr(0), AfterConstruct,
e->getNthExpr(2), BeforeConstruct);
addEdge(e1, AfterConstruct,
q->getNo(), AfterConstruct);
e->getNthExpr(2), AfterConstruct);
noFallThrough(e1);
} else {
addEdge(q->getCondition(), AfterConstruct,
q->getNo(), AfterConstruct);
addEdge(e->getNthExpr(0), AfterConstruct,
e->getNthExpr(2), AfterConstruct);
}
break;
}
default:
break;
}
@@ -597,36 +586,32 @@ void ControlFlowBuilder::getTrueFalseBranches(
ConstructPtr c(top(level));
if (StatementPtr s = dynamic_pointer_cast<Statement>(c)) {
StatementPtr kidBody;
int kidBodyIdx = -1;
switch (s->getKindOf()) {
case Statement::KindOfForStatement: {
case Statement::KindOfForStatement:
// examine which context we're in
ForStatementPtr fs(static_pointer_cast<ForStatement>(s));
ConstructPtr kid(top(level - 1));
if (kid == fs->getInitExp()) {
; // just do the default case
} else if (kid == fs->getCondExp()) {
kidBody = fs->getBody();
goto loop_stmt;
} else if (kid == fs->getIncExp()) {
; // just do the default case
} else {
assert(false);
{
ConstructPtr kid(top(level - 1));
if (kid == s->getNthKid(ForStatement::InitExpr)) {
; // just do the default case
} else if (kid == s->getNthKid(ForStatement::CondExpr)) {
kidBodyIdx = ForStatement::BodyStmt;
goto loop_stmt;
} else if (kid == s->getNthKid(ForStatement::IncExpr)) {
; // just do the default case
} else {
assert(false);
}
}
break;
}
case Statement::KindOfWhileStatement: {
WhileStatementPtr ws(static_pointer_cast<WhileStatement>(s));
kidBody = ws->getBody();
case Statement::KindOfWhileStatement:
kidBodyIdx = WhileStatement::BodyStmt;
goto loop_stmt;
}
case Statement::KindOfDoStatement: {
DoStatementPtr ds(static_pointer_cast<DoStatement>(s));
kidBody = ds->getBody();
}
case Statement::KindOfDoStatement:
kidBodyIdx = DoStatement::BodyStmt;
loop_stmt:
if (!trueBranch) {
trueBranch = kidBody;
trueBranch = s->getNthKid(kidBodyIdx);
tLoc = BeforeConstruct;
}
if (!falseBranch) {
@@ -867,7 +852,7 @@ ControlFlowGraph *ControlFlowGraph::buildControlFlow(MethodStatementPtr m) {
ControlFlowGraph *graph = new ControlFlowGraph;
graph->m_stmt = m;
ControlFlowBuilder cfb(graph);
ControlFlowBuilder cfb(graph, m->getOrigGeneratorFunc());
cfb.run(m->getStmts());
graph->m_nextDfn = 1;
depth_first_visit(*graph, cfb.head(),
+8 -13
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,17 +14,17 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CONTROL_FLOW_H_
#define incl_HPHP_CONTROL_FLOW_H_
#ifndef __CONTROL_FLOW_H__
#define __CONTROL_FLOW_H__
#include <boost/graph/properties.hpp>
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/graph/adjacency_list.hpp>
#include "hphp/compiler/hphp.h"
#include <compiler/hphp.h>
#include "hphp/compiler/analysis/ast_walker.h"
#include "hphp/compiler/analysis/bit_set_vec.h"
#include <compiler/analysis/ast_walker.h>
#include <compiler/analysis/bit_set_vec.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -65,8 +65,6 @@ struct graph_traits<HPHP::ControlFlowGraph> {
typedef int vertices_size_type;
typedef int edges_size_type;
typedef std::list<HPHP::ControlEdge*>::size_type degree_size_type;
static vertex_descriptor null_vertex() { return nullptr; }
};
template<>
@@ -311,10 +309,7 @@ inline void put(boost::vertex_color_t c,
class ControlFlowGraphWalker : public FunctionWalker {
public:
explicit ControlFlowGraphWalker(ControlFlowGraph *g)
: m_block(0)
, m_graph(*g)
{}
ControlFlowGraphWalker(ControlFlowGraph *g) : m_block(0), m_graph(*g) {}
template <class T>
void walk(T &t) {
std::pair<ControlFlowGraph::vertex_iterator,
@@ -338,4 +333,4 @@ protected:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CONTROL_FLOW_H_
#endif // __CONTROL_FLOW_H__
-1
Ver Arquivo
@@ -43,5 +43,4 @@ CODE_ERROR_ENTRY(InvalidTraitStatement)
CODE_ERROR_ENTRY(RedeclaredTrait)
CODE_ERROR_ENTRY(InvalidInstantiation)
CODE_ERROR_ENTRY(InvalidYield)
CODE_ERROR_ENTRY(InvalidAwait)
CODE_ERROR_ENTRY(BadDefaultValueType)
+15 -16
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,12 +14,12 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/data_flow.h"
#include "compiler/analysis/data_flow.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/expression/binary_op_expression.h"
#include "hphp/compiler/expression/list_assignment.h"
#include "compiler/expression/expression.h"
#include "compiler/expression/simple_variable.h"
#include "compiler/expression/binary_op_expression.h"
#include "compiler/expression/list_assignment.h"
using namespace HPHP;
using std::pair;
@@ -221,16 +221,16 @@ void DataFlow::ComputePartialDying(const ControlFlowGraph &g) {
// DataFlowWalker
int DataFlowWalker::after(ConstructRawPtr cp) {
if (ExpressionRawPtr e = dynamic_pointer_cast<Expression>(cp)) {
if (ExpressionRawPtr e = boost::dynamic_pointer_cast<Expression>(cp)) {
switch (e->getKindOf()) {
case Expression::KindOfSimpleVariable:
if (!static_pointer_cast<SimpleVariable>(
if (!boost::static_pointer_cast<SimpleVariable>(
e)->getAlwaysStash()) {
return WalkContinue;
}
break;
case Expression::KindOfBinaryOpExpression:
if (static_pointer_cast<BinaryOpExpression>(
if (boost::static_pointer_cast<BinaryOpExpression>(
e)->isShortCircuitOperator()) {
break;
}
@@ -246,7 +246,7 @@ int DataFlowWalker::after(ConstructRawPtr cp) {
for (int i = 0, nk = e->getKidCount(); i < nk; i++) {
ExpressionPtr k = e->getNthExpr(i);
if (k && k->is(Expression::KindOfSimpleVariable) &&
!static_pointer_cast<SimpleVariable>(
!boost::static_pointer_cast<SimpleVariable>(
k)->getAlwaysStash()) {
process(k);
}
@@ -260,13 +260,13 @@ int DataFlowWalker::after(ConstructRawPtr cp) {
}
int DataFlowWalker::afterEach(ConstructRawPtr cur, int i, ConstructRawPtr kid) {
if (ExpressionRawPtr k = dynamic_pointer_cast<Expression>(kid)) {
if (ExpressionRawPtr k = boost::dynamic_pointer_cast<Expression>(kid)) {
if (k->is(Expression::KindOfSimpleVariable) &&
!static_pointer_cast<SimpleVariable>(k)->getAlwaysStash()) {
if (ExpressionRawPtr e = dynamic_pointer_cast<Expression>(cur)) {
!boost::static_pointer_cast<SimpleVariable>(k)->getAlwaysStash()) {
if (ExpressionRawPtr e = boost::dynamic_pointer_cast<Expression>(cur)) {
switch (e->getKindOf()) {
case Expression::KindOfBinaryOpExpression:
if (!static_pointer_cast<BinaryOpExpression>(
if (!boost::static_pointer_cast<BinaryOpExpression>(
e)->isShortCircuitOperator()) {
return WalkContinue;
}
@@ -350,13 +350,12 @@ void DataFlowWalker::process(ExpressionPtr e, bool doAccessChains) {
case Expression::KindOfAssignmentExpression:
case Expression::KindOfBinaryOpExpression:
case Expression::KindOfUnaryOpExpression: {
ExpressionPtr var = e->getStoreVariable();
ExpressionPtr var = e->getNthExpr(0);
if (var && var->getContext() & (Expression::AssignmentLHS|
Expression::OprLValue)) {
processAccessChain(var);
processAccess(var);
}
// fall through
}
default:
processAccess(e);
+7 -7
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_DATA_FLOW_H_
#define incl_HPHP_DATA_FLOW_H_
#ifndef __DATA_FLOW_H__
#define __DATA_FLOW_H__
#include "hphp/compiler/analysis/bit_set_vec.h"
#include "hphp/compiler/analysis/control_flow.h"
#include <compiler/analysis/bit_set_vec.h>
#include <compiler/analysis/control_flow.h>
namespace HPHP {
@@ -91,7 +91,7 @@ private:
class DataFlowWalker : public ControlFlowGraphWalker {
public:
explicit DataFlowWalker(ControlFlowGraph *g) : ControlFlowGraphWalker(g) {}
DataFlowWalker(ControlFlowGraph *g) : ControlFlowGraphWalker(g) {}
template<class T>
void walk(T &t) { ControlFlowGraphWalker::walk(t); }
@@ -107,4 +107,4 @@ public:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_DATA_FLOW_H_
#endif // __DATA_FLOW_H__
+12 -12
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,15 +14,15 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_DEPTH_FIRST_VISITOR_H_
#define incl_HPHP_DEPTH_FIRST_VISITOR_H_
#ifndef __DEPTH_FIRST_VISITOR_H__
#define __DEPTH_FIRST_VISITOR_H__
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/ast_walker.h"
#include "hphp/compiler/analysis/block_scope.h"
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/ast_walker.h>
#include <compiler/analysis/block_scope.h>
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/statement/statement.h"
#include <compiler/expression/expression.h>
#include <compiler/statement/statement.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -64,12 +64,12 @@ public:
}
StatementPtr visitStmtRecur(StatementPtr stmt) {
BlockScopeRawPtr scope = dynamic_pointer_cast<LoopStatement>(stmt) ?
BlockScopeRawPtr scope = boost::dynamic_pointer_cast<LoopStatement>(stmt) ?
stmt->getScope() : BlockScopeRawPtr();
for (int i = 0, n = stmt->getKidCount(); i < n; i++) {
if (ConstructPtr kid = stmt->getNthKid(i)) {
if (StatementPtr s = dynamic_pointer_cast<Statement>(kid)) {
if (StatementPtr s = boost::dynamic_pointer_cast<Statement>(kid)) {
if (FunctionWalker::SkipRecurse(s)) continue;
if (scope) scope->incLoopNestedLevel();
if (StatementPtr rep = visitStmtRecur(s)) {
@@ -78,7 +78,7 @@ public:
}
if (scope) scope->decLoopNestedLevel();
} else {
ExpressionPtr e = dynamic_pointer_cast<Expression>(kid);
ExpressionPtr e = boost::dynamic_pointer_cast<Expression>(kid);
if (ExpressionPtr rep = visitExprRecur(e)) {
stmt->setNthKid(i, rep);
stmt->getScope()->addUpdates(BlockScope::UseKindCaller);
@@ -230,4 +230,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_DEPTH_FIRST_VISITOR_H_
#endif // __DEPTH_FIRST_VISITOR_H__
+9 -9
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,12 +14,12 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/alias_manager.h"
#include "hphp/compiler/analysis/dictionary.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/statement_list.h"
#include <compiler/analysis/alias_manager.h>
#include <compiler/analysis/dictionary.h>
#include <compiler/expression/expression.h>
#include <compiler/statement/statement.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/statement_list.h>
using namespace HPHP;
using std::vector;
@@ -39,11 +39,11 @@ void Dictionary::build(MethodStatementPtr m) {
void Dictionary::build(StatementPtr stmt) {
for (int i = 0, n = stmt->getKidCount(); i < n; i++) {
if (ConstructPtr kid = stmt->getNthKid(i)) {
if (StatementPtr s = dynamic_pointer_cast<Statement>(kid)) {
if (StatementPtr s = boost::dynamic_pointer_cast<Statement>(kid)) {
if (FunctionWalker::SkipRecurse(s)) continue;
build(s);
} else {
ExpressionPtr e = dynamic_pointer_cast<Expression>(kid);
ExpressionPtr e = boost::dynamic_pointer_cast<Expression>(kid);
build(e);
}
}
+7 -7
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_DICTIONARY_H_
#define incl_HPHP_DICTIONARY_H_
#ifndef __DICTIONARY_H__
#define __DICTIONARY_H__
#include "hphp/compiler/hphp.h"
#include "hphp/compiler/analysis/data_flow.h"
#include <compiler/hphp.h>
#include <compiler/analysis/data_flow.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -32,7 +32,7 @@ class Dictionary {
public:
typedef std::vector<ExpressionPtr> IdMap;
explicit Dictionary(AliasManager &am);
Dictionary(AliasManager &am);
void build(MethodStatementPtr s);
void build(StatementPtr s);
void build(ExpressionPtr s);
@@ -78,4 +78,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_DICTIONARY_H_
#endif // __DICTIONARY_H__
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+77 -129
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,19 +14,18 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_COMPILER_EMITTER_H_
#define incl_HPHP_COMPILER_EMITTER_H_
#ifndef __COMPILER_EMITTER_H__
#define __COMPILER_EMITTER_H__
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/statement/use_trait_statement.h"
#include "hphp/compiler/statement/trait_prec_statement.h"
#include "hphp/compiler/statement/trait_alias_statement.h"
#include "hphp/compiler/statement/typedef_statement.h"
#include <compiler/expression/expression.h>
#include <compiler/statement/statement.h>
#include <compiler/statement/use_trait_statement.h>
#include <compiler/statement/trait_prec_statement.h>
#include <compiler/statement/trait_alias_statement.h>
#include "hphp/runtime/vm/func.h"
#include "hphp/runtime/vm/unit.h"
#include "hphp/util/hash.h"
#include <runtime/vm/func.h>
#include <runtime/vm/unit.h>
#include <util/hash.h>
namespace HPHP {
@@ -41,12 +40,20 @@ DECLARE_BOOST_TYPES(SimpleFunctionCall);
DECLARE_BOOST_TYPES(SwitchStatement);
DECLARE_BOOST_TYPES(ForEachStatement);
class StaticClassName;
class HhbcExtFuncInfo;
class HhbcExtClassInfo;
namespace Compiler {
///////////////////////////////////////////////////////////////////////////////
using VM::Offset;
using VM::Func;
using VM::Class;
using VM::Unit;
using VM::InvalidAbsoluteOffset;
using VM::Opcode;
using VM::Id;
using namespace VM;
// Forward declarations.
class Label;
class EmitterVisitor;
@@ -89,12 +96,6 @@ public:
Id str;
Label* dest;
};
struct IterPair {
IterPair(IterKind k, Id i) : kind(k), id(i) {}
IterKind kind;
Id id;
};
#define O(name, imm, pop, push, flags) \
void name(imm);
#define NA
@@ -109,9 +110,8 @@ public:
#define MA std::vector<uchar>
#define BLA std::vector<Label*>&
#define SLA std::vector<StrOff>&
#define ILA std::vector<IterPair>&
#define IVA int32_t
#define LA int32_t
#define HA int32_t
#define IA int32_t
#define I64A int64_t
#define DA double
@@ -129,9 +129,8 @@ public:
#undef MA
#undef BLA
#undef SLA
#undef ILA
#undef IVA
#undef LA
#undef HA
#undef IA
#undef I64A
#undef DA
@@ -285,7 +284,7 @@ public:
class Label {
public:
Label() : m_off(InvalidAbsoluteOffset) {}
explicit Label(Emitter& e) : m_off(InvalidAbsoluteOffset) {
Label(Emitter& e) : m_off(InvalidAbsoluteOffset) {
set(e);
}
Offset getAbsoluteOffset() const { return m_off; }
@@ -324,7 +323,7 @@ public:
class EmitterVisitor {
friend class UnsetUnnamedLocalThunklet;
public:
explicit EmitterVisitor(UnitEmitter& ue);
EmitterVisitor(UnitEmitter& ue);
~EmitterVisitor();
bool visit(ConstructPtr c);
@@ -333,7 +332,7 @@ public:
void visit(FileScopePtr file);
void assignLocalVariableIds(FunctionScopePtr fs);
void fixReturnType(Emitter& e, FunctionCallPtr fn,
Func* builtinFunc = nullptr);
bool isBuiltinCall = false);
typedef std::vector<int> IndexChain;
void visitListAssignmentLHS(Emitter& e, ExpressionPtr exp,
IndexChain& indexChain,
@@ -348,10 +347,9 @@ 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 popSymbolicLocal(Opcode opcode, int arg = -1, int pos = -1);
void popEvalStackLMany();
void popEvalStackMany(int len, char symFlavor);
void popEvalStackCVMany(int len);
void pushEvalStack(char symFlavor);
void peekEvalStack(char symFlavor, int depthActual);
void pokeEvalStack(char symFlavor, int depthActual);
@@ -361,10 +359,9 @@ public:
recordJumpTarget(target, m_evalStack);
}
void restoreJumpTargetEvalStack();
void recordCall();
bool isJumpTarget(Offset target);
void setPrevOpcode(Op op) { m_prevOpcode = op; }
Op getPrevOpcode() const { return m_prevOpcode; }
void setPrevOpcode(Opcode op) { m_prevOpcode = op; }
Opcode getPrevOpcode() const { return m_prevOpcode; }
bool currentPositionIsReachable() {
return (m_ue.bcPos() == m_curFunc->base()
|| isJumpTarget(m_ue.bcPos())
@@ -374,29 +371,28 @@ public:
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) {
m_pendingIters.emplace_back(id, kind);
enum IterKind {
KindOfIter = 0,
KindOfMIter = 1
};
void pushIterScope(Id id, bool itRef = false) {
IterKind itKind = itRef ? KindOfMIter : KindOfIter;
m_pendingIters.push_back(std::pair<Id,IterKind>(id,itKind));
}
void popIterScope() { m_pendingIters.pop_back(); }
private:
typedef std::pair<StringData*, bool> ClosureUseVar; // (name, byRef)
typedef std::vector<ClosureUseVar> ClosureUseVarVec;
typedef std::vector<std::pair<Id,IterKind> > PendingIterVec;
typedef std::pair<StringData*, ExpressionPtr> NonScalarPair;
typedef std::vector<NonScalarPair> NonScalarVec;
typedef std::pair<Id, int> StrCase;
class PostponedMeth {
public:
PostponedMeth(MethodStatementPtr m, FuncEmitter* fe, bool top,
@@ -407,7 +403,6 @@ private:
bool m_top;
ClosureUseVarVec* m_closureUseVars;
};
class PostponedCtor {
public:
PostponedCtor(InterfaceStatementPtr is, FuncEmitter* fe)
@@ -415,7 +410,8 @@ private:
InterfaceStatementPtr m_is;
FuncEmitter* m_fe;
};
typedef std::pair<StringData*, ExpressionPtr> NonScalarPair;
typedef std::vector<NonScalarPair> NonScalarVec;
class PostponedNonScalars {
public:
PostponedNonScalars(InterfaceStatementPtr is, FuncEmitter* fe,
@@ -428,7 +424,6 @@ private:
FuncEmitter* m_fe;
NonScalarVec* m_vec;
};
class PostponedClosureCtor {
public:
PostponedClosureCtor(ClosureUseVarVec& v, ClosureExpressionPtr e,
@@ -438,32 +433,32 @@ private:
ClosureExpressionPtr m_expr;
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)
{}
ControlTargets(Id itId, bool itRef, Label& brkTarg, Label& cntTarg,
Label& brkHand, Label& cntHand) :
m_itId(itId), m_itRef(itRef), m_brkTarg(brkTarg), m_cntTarg(cntTarg),
m_brkHand(brkHand), m_cntHand(cntHand) {}
Id m_itId;
bool m_itRef;
Label& m_brkTarg; // Jump here for "break;" (after doing IterFree)
Label& m_cntTarg; // Jump here for "continue;"
Label& m_brkHand; // Push N and jump here for "break N;"
Label& m_cntHand; // Push N and jump here for "continue N;"
};
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));
Label& cntTarg, Label& brkHand, Label& cntHand) : m_e(e) {
e->m_contTargets.push_front(ControlTargets(itId, itRef, brkTarg, cntTarg,
brkHand, cntHand));
}
~ControlTargetPusher() {
m_e->m_controlTargets.pop_front();
m_e->m_contTargets.pop_front();
}
private:
EmitterVisitor* m_e;
};
class ExnHandlerRegion {
public:
ExnHandlerRegion(Offset start, Offset end) : m_start(start),
@@ -479,23 +474,15 @@ private:
std::set<StringData*, string_data_lt> m_names;
std::vector<std::pair<StringData*, Label*> > m_catchLabels;
};
class FaultRegion {
public:
FaultRegion(Offset start, Offset end, Id iterId, IterKind kind)
: m_start(start)
, m_end(end)
, m_iterId(iterId)
, m_iterKind(kind)
{}
FaultRegion(Offset start, Offset end, Id iterId)
: m_start(start), m_end(end), m_iterId(iterId) {}
Offset m_start;
Offset m_end;
Id m_iterId;
IterKind m_iterKind;
Label m_func; // note: a pointer to this is handed out to the Funclet
Label m_func;
};
class FPIRegion {
public:
FPIRegion(Offset start, Offset end, Offset fpOff)
@@ -504,7 +491,7 @@ private:
Offset m_end;
Offset m_fpOff;
};
typedef std::pair<Id, int> StrCase;
struct SwitchState : private boost::noncopyable {
SwitchState() : nonZeroI(-1), defI(-1) {}
std::map<int64_t, int> cases; // a map from int (or litstr id) to case index
@@ -515,13 +502,12 @@ private:
int defI;
};
private:
static const size_t kMinStringSwitchCases = 8;
UnitEmitter& m_ue;
FuncEmitter* m_curFunc;
FileScopePtr m_file;
Op m_prevOpcode;
Opcode m_prevOpcode;
std::deque<PostponedMeth> m_postponedMeths;
std::deque<PostponedCtor> m_postponedCtors;
@@ -530,29 +516,28 @@ private:
std::deque<PostponedNonScalars> m_postponedCinits;
std::deque<PostponedClosureCtor> m_postponedClosureCtors;
PendingIterVec m_pendingIters;
hphp_hash_map<std::string,FuncEmitter*> m_generatorEmitted;
hphp_hash_set<std::string> m_nonTopGeneratorEmitted;
hphp_hash_set<std::string> m_topMethodEmitted;
typedef std::map<const StringData*, Label*, string_data_lt> LabelMap;
LabelMap m_methLabels;
SymbolicStack m_evalStack;
bool m_evalStackIsUnknown;
hphp_hash_map<Offset, SymbolicStack> m_jumpTargetEvalStacks;
int m_actualStackHighWater;
int m_fdescHighWater;
typedef tbb::concurrent_hash_map<const StringData*, int,
StringDataHashCompare> EmittedClosures;
static EmittedClosures s_emittedClosures;
std::deque<ControlTargets> m_controlTargets;
int m_closureCounter; // used to uniquify closures' mangled names
std::deque<ControlTargets> m_contTargets;
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::vector<HphpArray*> 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;
MetaInfoBuilder m_metaInfo;
public:
Label& topBreakHandler() { return m_contTargets.front().m_brkHand; }
Label& topContHandler() { return m_contTargets.front().m_cntHand; }
bool checkIfStackEmpty(const char* forInstruction) const;
void unexpectedStackSym(char sym, const char* where) const;
@@ -580,8 +565,7 @@ public:
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);
void emitUnset(Emitter& e);
void emitSet(Emitter& e);
void emitSetOp(Emitter& e, int op);
void emitBind(Emitter& e);
@@ -598,10 +582,8 @@ public:
template<class Expr> void emitVirtualClassBase(Emitter&, Expr* node);
void emitResolveClsBase(Emitter& e, int pos);
void emitClsIfSPropBase(Emitter& e);
Id emitVisitAndSetUnnamedL(Emitter& e, ExpressionPtr exp);
Id emitSetUnnamedL(Emitter& e);
void emitPushAndFreeUnnamedL(Emitter& e, Id tempLocal, Offset start);
void emitContinuationSwitch(Emitter& e, int ncase);
Label* getContinuationGotoLabel(StatementPtr s);
void emitContinuationSwitch(Emitter& e, SwitchStatementPtr s);
DataType analyzeSwitch(SwitchStatementPtr s, SwitchState& state);
void emitIntegerSwitch(Emitter& e, SwitchStatementPtr s,
std::vector<Label>& caseLabels, Label& done,
@@ -609,7 +591,6 @@ 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);
@@ -629,32 +610,6 @@ public:
void postponeSinit(InterfaceStatementPtr m, FuncEmitter* fe, NonScalarVec* v);
void postponeCinit(InterfaceStatementPtr m, FuncEmitter* fe, NonScalarVec* v);
void emitPostponedMeths();
void bindUserAttributes(MethodStatementPtr meth,
FuncEmitter *fe,
bool &allowOverride);
void bindNativeFunc(MethodStatementPtr meth, FuncEmitter *fe);
void emitMethodMetadata(MethodStatementPtr meth,
ClosureUseVarVec* useVars,
bool top);
void fillFuncEmitterParams(FuncEmitter* fe,
ExpressionListPtr params,
bool builtin = false);
void emitMethodPrologue(Emitter& e, MethodStatementPtr meth);
void emitMethod(MethodStatementPtr meth);
std::pair<FuncEmitter*,bool> createFuncEmitterForGeneratorBody(
MethodStatementPtr meth,
FuncEmitter* fe,
vector<FuncEmitter*>& top_fes);
void emitAsyncMethod(MethodStatementPtr meth);
void emitGeneratorCreate(MethodStatementPtr meth);
void emitGeneratorBody(MethodStatementPtr meth);
void emitConstMethodCallNoParams(Emitter& e, string name);
void emitCreateStaticWaitHandle(Emitter& e, std::string cls,
std::function<void()> emitParam);
void emitSetFuncGetArgs(Emitter& e);
void emitMethodDVInitializers(Emitter& e,
MethodStatementPtr& meth,
Label& topOfBody);
void emitPostponedCtors();
void emitPostponedPSinit(PostponedNonScalars& p, bool pinit);
void emitPostponedPinits();
@@ -674,38 +629,31 @@ public:
};
bool emitCallUserFunc(Emitter& e, SimpleFunctionCallPtr node);
Func* canEmitBuiltinCall(const std::string& name, int numParams);
bool canEmitBuiltinCall(FunctionCallPtr fn, const std::string& name,
int numParams);
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,
int vLocalId);
PreClass::Hoistable emitClass(Emitter& e, ClassScopePtr cNode,
bool topLevel);
void emitBreakHandler(Emitter& e, Label& brkTarg, Label& cntTarg,
Label& brkHand, Label& cntHand, Id iter = -1,
IterKind itKind = KindOfIter);
void emitForeach(Emitter& e, ForEachStatementPtr fe);
void emitRestoreErrorReporting(Emitter& e, Id oldLevelLoc);
void emitMakeUnitFatal(Emitter& e,
const char* msg,
FatalKind k = FatalKind::Runtime,
bool skipFrame = false);
void emitMakeUnitFatal(Emitter& e, const std::string& message);
void addFunclet(Thunklet* body, Label* entry);
void emitFunclets(Emitter& e);
struct FaultIterInfo {
Id iterId;
IterKind kind;
};
void newFaultRegion(Offset start, Offset end, Thunklet* t,
FaultIterInfo = FaultIterInfo { -1, KindOfIter });
void newFaultRegion(Offset start, Offset end, Thunklet* t, Id iter = -1);
void newFPIRegion(Offset start, Offset end, Offset fpOff);
void copyOverExnHandlers(FuncEmitter* fe);
void copyOverFPIRegions(FuncEmitter* fe);
void saveMaxStackCells(FuncEmitter* fe);
void finishFunc(Emitter& e, FuncEmitter* fe);
StringData* newClosureName();
void initScalar(TypedValue& tvVal, ExpressionPtr val);
bool requiresDeepInit(ExpressionPtr initExpr) const;
@@ -731,4 +679,4 @@ extern "C" {
}
}
#endif // incl_HPHP_COMPILER_EMITTER_H_
#endif // __COMPILER_EMITTER_H__
+9 -9
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,14 +14,14 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/expr_dict.h"
#include "hphp/compiler/analysis/alias_manager.h"
#include <compiler/analysis/alias_manager.h>
#include <compiler/analysis/expr_dict.h>
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/assignment_expression.h"
#include <compiler/expression/expression.h>
#include <compiler/expression/assignment_expression.h>
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include <compiler/statement/statement.h>
#include <compiler/statement/method_statement.h>
using namespace HPHP;
using std::vector;
@@ -59,7 +59,7 @@ void ExprDict::getTypes(ExpressionPtr e, TypePtrIdxPairVec &types) {
class TypeFunc { public:
bool operator()(const TypePtrIdxPair& entry) const {
return entry.first != nullptr;
return entry.first;
}
};
static TypeFunc s_type_func;
@@ -313,7 +313,7 @@ void ExprDict::updateAccess(ExpressionPtr e) {
BitOps::set_bit(aid, m_altered, true);
}
if (!(cls & Expression::Store) ||
a != e->getStoreVariable()) {
a != e->getNthExpr(0)) {
a->clearAvailable();
m_avlAccess[i] = m_avlAccess[--n];
m_avlAccess.resize(n);
+7 -7
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_EXPR_DICT_H_
#define incl_HPHP_EXPR_DICT_H_
#ifndef __EXPR_DICT_H__
#define __EXPR_DICT_H__
#include "hphp/compiler/analysis/dictionary.h"
#include <compiler/analysis/dictionary.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -27,7 +27,7 @@ typedef std::vector<TypePtrIdxPair> TypePtrIdxPairVec;
class ExprDict : public Dictionary {
public:
explicit ExprDict(AliasManager &am);
ExprDict(AliasManager &am);
/* Building the dictionary */
void build(MethodStatementPtr m);
void visit(ExpressionPtr e);
@@ -43,8 +43,8 @@ public:
TypePtr propagateType(ExpressionPtr e);
void getTypes(ExpressionPtr e, TypePtrIdxPairVec &types);
private:
/**
* types is filled with (type assertion, canon id for that type assertion)
* tuples
@@ -94,4 +94,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_EXPR_DICT_H_
#endif // __EXPR_DICT_H__
+38 -54
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,27 +14,27 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/statement/exp_statement.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/function_scope.h"
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/statement/statement_list.h>
#include <compiler/statement/exp_statement.h>
#include <compiler/option.h>
#include <compiler/analysis/constant_table.h>
#include <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"
#include "hphp/util/base.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/statement/function_statement.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/compiler/expression/include_expression.h"
#include "hphp/compiler/expression/user_attribute.h"
#include "hphp/runtime/base/complex-types.h"
#include <compiler/parser/parser.h>
#include <util/logger.h>
#include <util/util.h>
#include <util/base.h>
#include <compiler/expression/expression_list.h>
#include <compiler/statement/function_statement.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/expression/simple_function_call.h>
#include <compiler/expression/include_expression.h>
#include <compiler/expression/user_attribute.h>
#include <runtime/base/complex_types.h>
using namespace HPHP;
@@ -73,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) {
@@ -89,48 +90,25 @@ 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());
loc->file = file.getName().c_str();
loc->file = m_fileName.c_str();
loc->first(line, 0);
loc->last(line, 0);
BlockScopePtr scope;
ExpressionListPtr args(new ExpressionList(scope, loc));
args->addElement(Expression::MakeScalarExpression(ar, scope, loc, msg));
SimpleFunctionCallPtr e(
new SimpleFunctionCall(scope, loc, "throw_fatal", false, args,
ExpressionPtr()));
meth(e);
new SimpleFunctionCall(scope, loc, "throw_fatal", args, ExpressionPtr()));
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,
@@ -214,6 +192,13 @@ int FileScope::getGlobalAttribute() const {
return m_attributes.back();
}
bool FileScope::needPseudoMainVariables() const {
VariableTablePtr variables = m_pseudoMain->getVariables();
return
variables->getAttribute(VariableTable::ContainsDynamicVariable) ||
variables->getSymbols().size() > 0;
}
///////////////////////////////////////////////////////////////////////////////
ExpressionPtr FileScope::getEffectiveImpl(AnalysisResultConstPtr ar) const {
@@ -411,10 +396,9 @@ FunctionScopePtr FileScope::createPseudoMain(AnalysisResultConstPtr ar) {
StatementListPtr st = m_tree;
FunctionStatementPtr f
(new FunctionStatement(BlockScopePtr(), LocationPtr(),
ModifierExpressionPtr(),
false, pseudoMainName(),
ExpressionListPtr(), TypeAnnotationPtr(),
st, 0, "", ExpressionListPtr()));
ExpressionListPtr(), st, 0, "",
ExpressionListPtr()));
f->setFileLevel();
FunctionScopePtr pseudoMain(
new HPHP::FunctionScope(ar, true,
+23 -46
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,18 +14,16 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_FILE_SCOPE_H_
#define incl_HPHP_FILE_SCOPE_H_
#ifndef __FILE_SCOPE_H__
#define __FILE_SCOPE_H__
#include <map>
#include "hphp/compiler/analysis/block_scope.h"
#include "hphp/compiler/analysis/function_container.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/code_generator.h"
#include <compiler/analysis/block_scope.h>
#include <compiler/analysis/function_container.h>
#include <compiler/analysis/code_error.h>
#include <compiler/code_generator.h>
#include <boost/graph/adjacency_list.hpp>
#include "hphp/util/json.h"
#include "hphp/util/md5.h"
#include <util/json.h>
#include <runtime/base/md5.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -61,7 +59,7 @@ public:
MixedVariableArgument = 0x800, // variable args, may or may not be ref'd
IsFoldable = 0x1000,// function can be constant folded
NeedsActRec = 0x2000,// builtin function needs ActRec
AllowOverride = 0x4000,// allow override of systemlib or builtin
IgnoreRedefinition = 0x4000,// ignore redefinition of builtin function
};
typedef boost::adjacency_list<boost::setS, boost::vecS> Graph;
@@ -107,11 +105,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);
@@ -140,23 +135,6 @@ public:
void addConstantDependency(AnalysisResultPtr ar,
const std::string &decname);
void addClassAlias(const std::string& target, const std::string& alias) {
m_classAliasMap.insert(std::make_pair(Util::toLower(target),
Util::toLower(alias)));
}
std::multimap<std::string,std::string> const& getClassAliases() const {
return m_classAliasMap;
}
void addTypeAliasName(const std::string& name) {
m_typeAliasNames.insert(Util::toLower(name));
}
std::set<std::string> const& getTypeAliasNames() const {
return m_typeAliasNames;
}
/**
* Called only by World
*/
@@ -184,17 +162,24 @@ public:
const std::string &pseudoMainName();
void outputFileCPP(AnalysisResultPtr ar, CodeGenerator &cg);
bool load();
bool needPseudoMainVariables() const;
std::string outputFilebase() const;
void addPseudoMainVariable(const std::string &name) {
m_pseudoMainVariables.insert(name);
}
std::set<std::string> &getPseudoMainVariables() {
return m_pseudoMainVariables;
}
FunctionScopeRawPtr getPseudoMain() const {
return m_pseudoMain;
}
FileScopePtr shared_from_this() {
return static_pointer_cast<FileScope>
return boost::static_pointer_cast<FileScope>
(BlockScope::shared_from_this());
}
private:
int m_size;
MD5 m_md5;
@@ -213,22 +198,14 @@ private:
vertex_descriptor m_vertex;
std::string m_pseudoMainName;
std::set<std::string> m_pseudoMainVariables;
BlockScopeSet m_providedDefs;
std::set<std::string> m_redecBases;
// Map from class alias names to the class they are aliased to.
// This is only needed in WholeProgram mode.
std::multimap<std::string,std::string> m_classAliasMap;
// Set of names that are on the left hand side of type alias
// declarations. We need this to make sure we don't mark classes
// with the same name Unique.
std::set<std::string> m_typeAliasNames;
FunctionScopePtr createPseudoMain(AnalysisResultConstPtr ar);
void setFileLevel(StatementListPtr stmt);
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_FILE_SCOPE_H_
#endif // __FILE_SCOPE_H__
+11 -11
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,16 +14,16 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/function_container.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/option.h"
#include "hphp/util/util.h"
#include "hphp/util/hash.h"
#include <compiler/analysis/function_container.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/code_error.h>
#include <compiler/statement/statement_list.h>
#include <compiler/option.h>
#include <util/util.h>
#include <util/hash.h>
using namespace HPHP;
+5 -5
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_FUNCTION_CONTAINER_H_
#define incl_HPHP_FUNCTION_CONTAINER_H_
#ifndef __FUNCTION_CONTAINER_H__
#define __FUNCTION_CONTAINER_H__
#include "hphp/compiler/hphp.h"
#include <compiler/hphp.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -56,4 +56,4 @@ protected:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_FUNCTION_CONTAINER_H_
#endif // __FUNCTION_CONTAINER_H__
+117 -96
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,31 +14,31 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/compiler/expression/modifier_expression.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/function_call.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/util/logger.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/exp_statement.h"
#include "hphp/compiler/expression/parameter_expression.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/util/atomic.h"
#include "hphp/util/util.h"
#include "hphp/runtime/base/class-info.h"
#include "hphp/runtime/base/type-conversions.h"
#include "hphp/runtime/base/builtin-functions.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/runtime/base/variable-serializer.h"
#include "hphp/runtime/base/zend-string.h"
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/expression/constant_expression.h>
#include <compiler/expression/modifier_expression.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/function_call.h>
#include <compiler/analysis/code_error.h>
#include <compiler/statement/statement_list.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/parser/parser.h>
#include <util/logger.h>
#include <compiler/option.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/exp_statement.h>
#include <compiler/expression/parameter_expression.h>
#include <compiler/analysis/class_scope.h>
#include <util/atomic.h>
#include <util/util.h>
#include <runtime/base/class_info.h>
#include <runtime/base/type_conversions.h>
#include <runtime/base/builtin_functions.h>
#include <util/parser/hphp.tab.hpp>
#include <runtime/base/variable_serializer.h>
#include <runtime/base/zend/zend_string.h>
using namespace HPHP;
@@ -58,17 +58,15 @@ FunctionScope::FunctionScope(AnalysisResultConstPtr ar, bool method,
m_method(method), m_refReturn(reference), m_virtual(false),
m_hasOverride(false), m_perfectVirtual(false), m_overriding(false),
m_volatile(false), m_persistent(false), m_pseudoMain(inPseudoMain),
m_magicMethod(false), m_system(false), m_inlineable(false),
m_magicMethod(false), m_system(false), m_inlineable(false), m_sep(false),
m_containsThis(false), m_containsBareThis(0), m_nrvoFix(true),
m_inlineAsExpr(false), m_inlineSameContext(false),
m_contextSensitive(false),
m_directInvoke(false),
m_generator(false),
m_async(false),
m_noLSB(false), m_nextLSB(false),
m_directInvoke(false), m_needsRefTemp(false),
m_needsObjTemp(false), m_needsCheckMem(false),
m_closureGenerator(false), m_noLSB(false), m_nextLSB(false),
m_hasTry(false), m_hasGoto(false), m_localRedeclaring(false),
m_redeclaring(-1), m_inlineIndex(0), m_optFunction(0), m_nextID(0),
m_yieldLabelCount(0), m_yieldLabelGen(-1) {
m_redeclaring(-1), m_inlineIndex(0), m_optFunction(0), m_nextID(0) {
init(ar);
for (unsigned i = 0; i < attrs.size(); ++i) {
if (m_userAttributes.find(attrs[i]->getName()) != m_userAttributes.end()) {
@@ -78,12 +76,6 @@ FunctionScope::FunctionScope(AnalysisResultConstPtr ar, bool method,
}
m_userAttributes[attrs[i]->getName()] = attrs[i]->getExp();
}
// Support for systemlib functions implemented in PHP
if (!m_method &&
m_userAttributes.find("__Overridable") != m_userAttributes.end()) {
setAllowOverride();
}
}
FunctionScope::FunctionScope(FunctionScopePtr orig,
@@ -91,8 +83,7 @@ FunctionScope::FunctionScope(FunctionScopePtr orig,
const string &name,
const string &originalName,
StatementPtr stmt,
ModifierExpressionPtr modifiers,
bool user)
ModifierExpressionPtr modifiers)
: BlockScope(name, orig->m_docComment, stmt,
BlockScope::FunctionScope),
m_minParam(orig->m_minParam), m_maxParam(orig->m_maxParam),
@@ -104,22 +95,22 @@ FunctionScope::FunctionScope(FunctionScopePtr orig,
m_overriding(orig->m_overriding), m_volatile(orig->m_volatile),
m_persistent(orig->m_persistent),
m_pseudoMain(orig->m_pseudoMain), m_magicMethod(orig->m_magicMethod),
m_system(!user), m_inlineable(orig->m_inlineable),
m_containsThis(orig->m_containsThis),
m_system(orig->m_system), m_inlineable(orig->m_inlineable),
m_sep(orig->m_sep), m_containsThis(orig->m_containsThis),
m_containsBareThis(orig->m_containsBareThis), m_nrvoFix(orig->m_nrvoFix),
m_inlineAsExpr(orig->m_inlineAsExpr),
m_inlineSameContext(orig->m_inlineSameContext),
m_contextSensitive(orig->m_contextSensitive),
m_directInvoke(orig->m_directInvoke),
m_generator(orig->m_generator),
m_async(orig->m_async),
m_noLSB(orig->m_noLSB),
m_needsRefTemp(orig->m_needsRefTemp),
m_needsObjTemp(orig->m_needsObjTemp),
m_needsCheckMem(orig->m_needsCheckMem),
m_closureGenerator(orig->m_closureGenerator), m_noLSB(orig->m_noLSB),
m_nextLSB(orig->m_nextLSB), m_hasTry(orig->m_hasTry),
m_hasGoto(orig->m_hasGoto), m_localRedeclaring(orig->m_localRedeclaring),
m_redeclaring(orig->m_redeclaring),
m_inlineIndex(orig->m_inlineIndex), m_optFunction(orig->m_optFunction),
m_nextID(0), m_yieldLabelCount(orig->m_yieldLabelCount),
m_yieldLabelGen(orig->m_yieldLabelGen) {
m_nextID(0) {
init(ar);
m_originalName = originalName;
setParamCounts(ar, m_minParam, m_maxParam);
@@ -208,14 +199,12 @@ FunctionScope::FunctionScope(bool method, const std::string &name,
m_method(method), m_refReturn(reference), m_virtual(false),
m_hasOverride(false), m_perfectVirtual(false), m_overriding(false),
m_volatile(false), m_persistent(false), m_pseudoMain(false),
m_magicMethod(false), m_system(true), m_inlineable(false),
m_magicMethod(false), m_system(true), m_inlineable(false), m_sep(false),
m_containsThis(false), m_containsBareThis(0), m_nrvoFix(true),
m_inlineAsExpr(false), m_inlineSameContext(false),
m_contextSensitive(false),
m_directInvoke(false),
m_generator(false),
m_async(false),
m_noLSB(false), m_nextLSB(false),
m_directInvoke(false), m_needsRefTemp(false), m_needsObjTemp(false),
m_closureGenerator(false), m_noLSB(false), m_nextLSB(false),
m_hasTry(false), m_hasGoto(false), m_localRedeclaring(false),
m_redeclaring(-1), m_inlineIndex(0),
m_optFunction(0) {
@@ -287,14 +276,6 @@ void FunctionScope::setParamSpecs(AnalysisResultPtr ar) {
}
}
bool FunctionScope::hasUserAttr(const char *attr) const {
return m_userAttributes.find(attr) != m_userAttributes.end();
}
bool FunctionScope::isZendParamMode() const {
return m_attributeClassInfo & ClassInfo::ZendParamMode;
}
bool FunctionScope::isPublic() const {
return m_modifiers && m_modifiers->isPublic();
}
@@ -315,10 +296,6 @@ bool FunctionScope::isAbstract() const {
return m_modifiers && m_modifiers->isAbstract();
}
bool FunctionScope::isNative() const {
return hasUserAttr("__native");
}
bool FunctionScope::isFinal() const {
return m_modifiers && m_modifiers->isFinal();
}
@@ -328,8 +305,8 @@ bool FunctionScope::isVariableArgument() const {
return res;
}
bool FunctionScope::allowOverride() const {
return m_attribute & FileScope::AllowOverride;
bool FunctionScope::ignoreRedefinition() const {
return m_attribute & FileScope::IgnoreRedefinition;
}
bool FunctionScope::isReferenceVariableArgument() const {
@@ -354,33 +331,39 @@ bool FunctionScope::needsActRec() const {
return res;
}
bool FunctionScope::mayContainThis() {
return inPseudoMain() || getContainingClass() ||
(isClosure() && !m_modifiers->isStatic());
}
bool FunctionScope::isClosure() const {
return ParserBase::IsClosureName(name());
}
int FunctionScope::allocYieldLabel() {
assert(m_yieldLabelGen >= 0);
return ++m_yieldLabelCount;
bool FunctionScope::isGenerator() const {
assert(!getOrigGenStmt() ||
(ParserBase::IsContinuationName(name()) &&
m_paramNames.size() == 1 &&
m_paramNames[0] == CONTINUATION_OBJECT_NAME));
return getOrigGenStmt();
}
int FunctionScope::getYieldLabelCount() const {
assert(m_yieldLabelGen >= 0);
return m_yieldLabelCount;
bool FunctionScope::hasGeneratorAsBody() const {
MethodStatementPtr stmt = dynamic_pointer_cast<MethodStatement>(getStmt());
return stmt ? stmt->getGeneratorFunc() : false;
}
int FunctionScope::getYieldLabelGeneration() const {
assert(m_yieldLabelGen >= 0);
return m_yieldLabelGen;
bool FunctionScope::isGeneratorFromClosure() const {
bool res = isGenerator() && getOrigGenFS()->isClosure();
assert(!res || getOrigGenFS()->isClosureGenerator());
return res;
}
void FunctionScope::resetYieldLabelCount() {
++m_yieldLabelGen;
m_yieldLabelCount = 0;
MethodStatementRawPtr FunctionScope::getOrigGenStmt() const {
if (!getStmt()) return MethodStatementRawPtr();
MethodStatementPtr m =
dynamic_pointer_cast<MethodStatement>(getStmt());
return m ? m->getOrigGeneratorFunc() : MethodStatementRawPtr();
}
FunctionScopeRawPtr FunctionScope::getOrigGenFS() const {
MethodStatementRawPtr origStmt = getOrigGenStmt();
return origStmt ? origStmt->getFunctionScope() : FunctionScopeRawPtr();
}
void FunctionScope::setVariableArgument(int reference) {
@@ -393,8 +376,8 @@ void FunctionScope::setVariableArgument(int reference) {
}
}
void FunctionScope::setAllowOverride() {
m_attribute |= FileScope::AllowOverride;
void FunctionScope::setIgnoreRedefinition() {
m_attribute |= FileScope::IgnoreRedefinition;
}
bool FunctionScope::hasEffect() const {
@@ -473,7 +456,7 @@ bool FunctionScope::hasImpl() const {
}
if (m_stmt) {
MethodStatementPtr stmt = dynamic_pointer_cast<MethodStatement>(m_stmt);
return stmt->getStmts() != nullptr;
return stmt->getStmts();
}
return false;
}
@@ -539,7 +522,6 @@ bool FunctionScope::mayUseVV() const {
return (inPseudoMain() ||
isVariableArgument() ||
isGenerator() ||
isAsync() ||
variables->getAttribute(VariableTable::ContainsDynamicVariable) ||
variables->getAttribute(VariableTable::ContainsExtract) ||
variables->getAttribute(VariableTable::ContainsCompact) ||
@@ -590,6 +572,18 @@ void FunctionScope::setPerfectVirtual() {
}
}
bool FunctionScope::needsTypeCheckWrapper() const {
for (int i = 0; i < m_maxParam; i++) {
if (isRefParam(i)) continue;
if (TypePtr spec = m_paramTypeSpecs[i]) {
if (Type::SameType(spec, m_paramTypes[i])) {
return true;
}
}
}
return false;
}
bool FunctionScope::needsClassParam() {
if (!isStatic()) return false;
ClassScopeRawPtr cls = getContainingClass();
@@ -665,8 +659,7 @@ int FunctionScope::inferParamTypes(AnalysisResultPtr ar, ConstructPtr exp,
/**
* Duplicate the logic of getParamType(i), w/o the mutation
*/
TypePtr paramType(i < m_maxParam && !isZendParamMode() ?
m_paramTypes[i] : TypePtr());
TypePtr paramType(i < m_maxParam ? m_paramTypes[i] : TypePtr());
if (!paramType) paramType = Type::Some;
if (valid && !canSetParamType && i < m_maxParam &&
(!Option::HardTypeHints || !m_paramTypeSpecs[i])) {
@@ -678,8 +671,8 @@ int FunctionScope::inferParamTypes(AnalysisResultPtr ar, ConstructPtr exp,
* expression since it'll just get converted anyways. Doing it this way
* allows us to generate less temporaries along the way.
*/
TypePtr optParamType(paramType->is(Type::KindOfVariant) ?
Type::Some : paramType);
TypePtr optParamType(
paramType->is(Type::KindOfVariant) ? Type::Some : paramType);
expType = param->inferAndCheck(ar, optParamType, false);
} else {
expType = param->inferAndCheck(ar, Type::Some, false);
@@ -786,10 +779,16 @@ void FunctionScope::setParamName(int index, const std::string &name) {
void FunctionScope::setParamDefault(int index, const char* value, int64_t len,
const std::string &text) {
assert(index >= 0 && index < (int)m_paramNames.size());
m_paramDefaults[index] = std::string(value, len);
StringData* sd = new StringData(value, len, AttachLiteral);
sd->setStatic();
m_paramDefaults[index] = String(sd);
m_paramDefaultTexts[index] = text;
}
CStrRef FunctionScope::getParamDefault(int index) {
return m_paramDefaults[index];
}
void FunctionScope::addModifier(int mod) {
if (!m_modifiers) {
m_modifiers =
@@ -855,7 +854,7 @@ bool FunctionScope::popReturnType() {
m_prevReturn.reset();
addUpdates(UseKindCallerReturn);
#ifdef HPHP_INSTRUMENT_TYPE_INF
++RescheduleException::s_NumRetTypesChanged;
atomic_inc(RescheduleException::s_NumRetTypesChanged);
#endif /* HPHP_INSTRUMENT_TYPE_INF */
return true;
}
@@ -929,6 +928,28 @@ std::string FunctionScope::getDocFullName() const {
return docName;
}
std::string FunctionScope::getInjectionId() const {
string injectionName = CodeGenerator::FormatLabel(getOriginalName());
MethodStatementPtr stmt =
dynamic_pointer_cast<MethodStatement>(getStmt());
assert(stmt);
if (stmt->getGeneratorFunc()) {
injectionName = isClosureGenerator() ?
injectionName :
injectionName + "{continuation}";
} else if (stmt->getOrigGeneratorFunc() &&
!getOrigGenFS()->isClosure()) {
injectionName = CodeGenerator::FormatLabel(
stmt->getOrigGeneratorFunc()->getOriginalName());
}
if (m_redeclaring < 0) {
return injectionName;
}
const string &redecSuffix = string(Option::IdPrefix) +
boost::lexical_cast<std::string>(m_redeclaring);
return injectionName + redecSuffix;
}
///////////////////////////////////////////////////////////////////////////////
void FunctionScope::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) {
@@ -1054,7 +1075,7 @@ bool FunctionScope::needsAnonClosureClass(ParameterExpressionPtrVec &useVars) {
useVars.clear();
if (!isClosure()) return false;
ParameterExpressionPtrIdxPairVec useVars0;
getClosureUseVars(useVars0, !m_generator && !m_async);
getClosureUseVars(useVars0, !m_closureGenerator);
useVars.resize(useVars0.size());
// C++ seems to be unable to infer the type here on pair_first_elem
transform(useVars0.begin(),
@@ -1068,7 +1089,7 @@ bool FunctionScope::needsAnonClosureClass(
ParameterExpressionPtrIdxPairVec &useVars) {
useVars.clear();
if (!isClosure()) return false;
getClosureUseVars(useVars, !m_generator && !m_async);
getClosureUseVars(useVars, !m_closureGenerator);
return useVars.size() > 0 || getVariables()->hasStaticLocals();
}
+46 -40
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,15 +14,15 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_FUNCTION_SCOPE_H_
#define incl_HPHP_FUNCTION_SCOPE_H_
#ifndef __FUNCTION_SCOPE_H__
#define __FUNCTION_SCOPE_H__
#include "hphp/compiler/expression/user_attribute.h"
#include "hphp/compiler/analysis/block_scope.h"
#include "hphp/compiler/option.h"
#include <compiler/expression/user_attribute.h>
#include <compiler/analysis/block_scope.h>
#include <compiler/option.h>
#include "hphp/util/json.h"
#include "hphp/parser/parser.h"
#include <util/json.h>
#include <util/parser/parser.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -73,7 +73,7 @@ public:
FunctionScope(FunctionScopePtr orig, AnalysisResultConstPtr ar,
const std::string &name, const std::string &originalName,
StatementPtr stmt, ModifierExpressionPtr modifiers, bool user);
StatementPtr stmt, ModifierExpressionPtr modifiers);
/**
* System functions.
@@ -84,24 +84,22 @@ public:
void setParamName(int index, const std::string &name);
void setParamDefault(int index, const char* value, int64_t len,
const std::string &text);
CStrRef getParamDefault(int index);
void setRefParam(int index);
bool hasRefParam(int max) const;
void addModifier(int mod);
bool hasUserAttr(const char *attr) const;
/**
* What kind of function this is.
*/
bool isUserFunction() const { return !m_system && !isNative(); }
bool isUserFunction() const { return !m_system;}
bool isDynamic() const { return m_dynamic; }
bool isPublic() const;
bool isProtected() const;
bool isPrivate() const;
bool isStatic() const;
bool isAbstract() const;
bool isNative() const;
bool isFinal() const;
bool isMagic() const;
bool isRefParam(int index) const;
@@ -111,18 +109,23 @@ public:
bool hasImpl() const;
void setDirectInvoke() { m_directInvoke = true; }
bool hasDirectInvoke() const { return m_directInvoke; }
bool isZendParamMode() const;
bool mayContainThis();
bool isClosure() const;
bool isGenerator() const { return m_generator; }
void setGenerator(bool f) { m_generator = f; }
int allocYieldLabel();
int getYieldLabelCount() const;
int getYieldLabelGeneration() const;
void resetYieldLabelCount();
bool isAsync() const { return m_async; }
void setAsync(bool f) { m_async = f; }
bool isGenerator() const;
bool isGeneratorFromClosure() const;
bool hasGeneratorAsBody() const;
MethodStatementRawPtr getOrigGenStmt() const;
FunctionScopeRawPtr getOrigGenFS() const;
void setNeedsRefTemp() { m_needsRefTemp = true; }
bool needsRefTemp() const { return m_needsRefTemp; }
void setNeedsObjTemp() { m_needsObjTemp = true; }
bool needsObjTemp() const { return m_needsObjTemp; }
void setNeedsCheckMem() { m_needsCheckMem = true; }
bool needsCheckMem() const { return m_needsCheckMem; }
void setClosureGenerator() { m_closureGenerator = true; }
bool isClosureGenerator() const {
assert(!m_closureGenerator || isClosure());
return m_closureGenerator;
}
bool needsClassParam();
void setInlineSameContext(bool f) { m_inlineSameContext = f; }
@@ -158,6 +161,7 @@ public:
}
virtual std::string getId() const;
std::string getInjectionId() const;
int getRedeclaringId() const {
return m_redeclaring;
@@ -221,10 +225,10 @@ public:
void setNeedsActRec();
/*
* If this is a builtin (C++ or PHP) and can be redefined
* If this is a builtin and can be redefined
*/
bool allowOverride() const;
void setAllowOverride();
bool ignoreRedefinition() const;
void setIgnoreRedefinition();
/**
* Whether this function is a runtime helper function
@@ -253,8 +257,6 @@ public:
/**
* What is the inferred type of this function's return.
* Note that for generators and async functions, this is different
* from what caller actually gets when calling the function.
*/
void pushReturnType();
void setReturnType(AnalysisResultConstPtr ar, TypePtr type);
@@ -268,6 +270,8 @@ public:
void clearRetExprs();
void fixRetExprs();
bool needsTypeCheckWrapper() const;
void setOptFunction(FunctionOptPtr fn) { m_optFunction = fn; }
FunctionOptPtr getOptFunction() const { return m_optFunction; }
@@ -309,6 +313,10 @@ public:
bool isInlined() const { return m_inlineable; }
void disableInline() { m_inlineable = false; }
/* Whether this function is brought in by a separable extension */
void setSepExtension() { m_sep = true;}
bool isSepExtension() const { return m_sep;}
/* Whether we need to worry about the named return value optimization
for this function */
void setNRVOFix(bool flag) { m_nrvoFix = flag; }
@@ -393,11 +401,8 @@ public:
class FunctionInfo {
public:
explicit FunctionInfo(int rva = -1)
: m_maybeStatic(false)
, m_maybeRefReturn(false)
, m_refVarArg(rva)
{}
FunctionInfo(int rva = -1) : m_maybeStatic(false), m_maybeRefReturn(false),
m_refVarArg(rva) { }
bool isRefParam(int p) const {
if (m_refVarArg >= 0 && p >= m_refVarArg) return true;
@@ -437,7 +442,7 @@ private:
std::vector<std::string> m_paramNames;
TypePtrVec m_paramTypes;
TypePtrVec m_paramTypeSpecs;
std::vector<std::string> m_paramDefaults;
std::vector<String> m_paramDefaults;
std::vector<std::string> m_paramDefaultTexts;
std::vector<bool> m_refs;
TypePtr m_returnType;
@@ -460,6 +465,7 @@ private:
unsigned m_magicMethod : 1;
unsigned m_system : 1;
unsigned m_inlineable : 1;
unsigned m_sep : 1;
unsigned m_containsThis : 1; // contains a usage of $this?
unsigned m_containsBareThis : 2; // $this outside object-context,
// 2 if in reference context
@@ -468,8 +474,10 @@ private:
unsigned m_inlineSameContext : 1;
unsigned m_contextSensitive : 1;
unsigned m_directInvoke : 1;
unsigned m_generator : 1;
unsigned m_async : 1;
unsigned m_needsRefTemp : 1;
unsigned m_needsObjTemp : 1;
unsigned m_needsCheckMem : 1;
unsigned m_closureGenerator : 1;
unsigned m_noLSB : 1;
unsigned m_nextLSB : 1;
unsigned m_hasTry : 1;
@@ -485,11 +493,9 @@ private:
ExpressionListPtr m_closureValues;
ReadWriteMutex m_inlineMutex;
unsigned m_nextID; // used when cloning generators for traits
int m_yieldLabelCount; // number of allocated yield labels
int m_yieldLabelGen; // generation counter for yield labels
std::list<FunctionScopeRawPtr> m_clonedTraitOuterScope;
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_FUNCTION_SCOPE_H_
#endif // __FUNCTION_SCOPE_H__
+18 -18
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,21 +14,20 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/live_dict.h"
#include <compiler/analysis/alias_manager.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/live_dict.h>
#include <compiler/analysis/variable_table.h>
#include "hphp/compiler/analysis/alias_manager.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/variable_table.h"
#include <compiler/expression/expression.h>
#include <compiler/expression/assignment_expression.h>
#include <compiler/expression/simple_variable.h>
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/assignment_expression.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/statement/block_statement.h"
#include "hphp/compiler/statement/exp_statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/statement_list.h"
#include <compiler/statement/statement.h>
#include <compiler/statement/block_statement.h>
#include <compiler/statement/exp_statement.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/statement_list.h>
using namespace HPHP;
using std::vector;
@@ -327,10 +326,10 @@ void LiveDict::updateAccess(ExpressionPtr e) {
}
struct Colorizer {
explicit Colorizer(int w) : toNode(w) {}
Colorizer(int w) : toNode(w) {}
struct NodeInfo {
explicit NodeInfo(int index) : originalIndex(index), size(0), color(-1) {}
NodeInfo(int index) : originalIndex(index), size(0), color(-1) {}
int originalIndex;
int size;
int color;
@@ -360,7 +359,7 @@ struct Colorizer {
class NodeCmp {
public:
explicit NodeCmp(const Colorizer *c) : m_c(c) {}
NodeCmp(const Colorizer *c) : m_c(c) {}
bool operator()(int a, int b) {
const NodeInfo &n1 = m_c->nodes[a];
const NodeInfo &n2 = m_c->nodes[b];
@@ -466,6 +465,7 @@ bool LiveDict::color(TypePtr type) {
if (sym &&
!sym->isGlobal() &&
!sym->isParameter() &&
!sym->isGeneratorParameter() &&
!sym->isClosureVar() &&
!sym->isStatic() &&
!e->isThis()) {
@@ -610,7 +610,7 @@ public:
SimpleVariablePtr sv(static_pointer_cast<SimpleVariable>(e));
Symbol *sym = sv->getSymbol();
if (!sym || sym->isGlobal() || sym->isStatic() || sym->isParameter() ||
sym->isClosureVar() || sv->isThis()) {
sym->isGeneratorParameter() || sym->isClosureVar() || sv->isThis()) {
continue;
}
+6 -6
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_LIVE_DICT_H_
#define incl_HPHP_LIVE_DICT_H_
#ifndef __LIVE_DICT_H__
#define __LIVE_DICT_H__
#include "hphp/compiler/analysis/dictionary.h"
#include <compiler/analysis/dictionary.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -26,7 +26,7 @@ namespace HPHP {
class LiveDict : public Dictionary {
public:
explicit LiveDict(AliasManager &am) : Dictionary(am) {}
LiveDict(AliasManager &am) : Dictionary(am) {}
/* Building the dictionary */
void build(MethodStatementPtr m);
void visit(ExpressionPtr e);
@@ -53,4 +53,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_LIVE_DICT_H_
#endif // __LIVE_DICT_H__
+15 -18
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,16 +14,18 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/peephole.h"
#include "hphp/compiler/analysis/emitter.h"
#include "hphp/runtime/vm/preclass-emit.h"
#include "compiler/analysis/peephole.h"
#include "compiler/analysis/emitter.h"
namespace HPHP { namespace Compiler {
using VM::FuncEmitter;
using VM::UnitEmitter;
using VM::Offset;
static void collapseJmp(Offset* offsetPtr, Op* instr, Op* start) {
static void collapseJmp(Offset* offsetPtr, Opcode* instr, Opcode* start) {
if (offsetPtr) {
Op* dest = instr + *offsetPtr;
Opcode* dest = instr + *offsetPtr;
while (*dest == OpJmp && dest != instr) {
dest = start + instrJumpTarget(start, dest - start);
}
@@ -43,10 +45,10 @@ Peephole::Peephole(UnitEmitter &ue, MetaInfoBuilder& metaInfo)
buildJumpTargets();
// Scan the bytecode linearly.
Op* start = (Op*)ue.m_bc;
Op* prev = start;
Op* cur = prev + instrLen(prev);
Op* end = start + ue.m_bclen;
Opcode* start = ue.m_bc;
Opcode* prev = start;
Opcode* cur = prev + instrLen(prev);
Opcode* end = start + ue.m_bclen;
/*
* TODO(1086005): we should try to minimize use of CGetL2/CGetL3.
@@ -162,19 +164,14 @@ void Peephole::buildJumpTargets() {
}
// all jump targets are targets
for (Offset pos = 0; pos < (Offset)m_ue.m_bclen;
pos += instrLen((Op*)&m_ue.m_bc[pos])) {
Op* instr = (Op*)&m_ue.m_bc[pos];
pos += instrLen(&m_ue.m_bc[pos])) {
Opcode* instr = &m_ue.m_bc[pos];
if (isSwitch(*instr)) {
foreachSwitchTarget(instr, [&](Offset& o) {
m_jumpTargets.insert(pos + o);
});
} else if (*instr == OpIterBreak) {
uint32_t veclen = *(uint32_t *)(instr + 1);
assert(veclen > 0);
Offset target = *(Offset *)((uint32_t *)(instr + 1) + 2 * veclen + 1);
m_jumpTargets.insert(pos + target);
} else {
Offset target = instrJumpTarget((Op*)m_ue.m_bc, pos);
Offset target = instrJumpTarget(m_ue.m_bc, pos);
if (target != InvalidAbsoluteOffset) {
m_jumpTargets.insert(target);
}
+7 -7
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -34,8 +34,8 @@
#ifndef incl_HPHP_COMPILER_ANALYSIS_PEEPHOLE_H_
#define incl_HPHP_COMPILER_ANALYSIS_PEEPHOLE_H_
#include "hphp/runtime/vm/unit.h"
#include "hphp/runtime/vm/func.h"
#include "runtime/vm/unit.h"
#include "runtime/vm/func.h"
namespace HPHP { namespace Compiler {
@@ -43,14 +43,14 @@ class MetaInfoBuilder;
class Peephole {
public:
Peephole(UnitEmitter& ue, MetaInfoBuilder& metaInfo);
Peephole(VM::UnitEmitter& ue, MetaInfoBuilder& metaInfo);
private:
void buildFuncTargets(FuncEmitter* fe);
void buildFuncTargets(VM::FuncEmitter* fe);
void buildJumpTargets();
UnitEmitter& m_ue;
hphp_hash_set<Offset> m_jumpTargets;
VM::UnitEmitter& m_ue;
hphp_hash_set<VM::Offset> m_jumpTargets;
};
}}
+29 -29
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,22 +14,22 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/ref_dict.h"
#include "hphp/compiler/analysis/alias_manager.h"
#include "hphp/compiler/analysis/function_scope.h"
#include <compiler/analysis/alias_manager.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/ref_dict.h>
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/assignment_expression.h"
#include "hphp/compiler/expression/binary_op_expression.h"
#include "hphp/compiler/expression/simple_variable.h"
#include <compiler/expression/expression.h>
#include <compiler/expression/assignment_expression.h>
#include <compiler/expression/binary_op_expression.h>
#include <compiler/expression/simple_variable.h>
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/statement/block_statement.h"
#include "hphp/compiler/statement/exp_statement.h"
#include "hphp/compiler/statement/method_statement.h"
#include "hphp/compiler/statement/statement_list.h"
#include <compiler/statement/statement.h>
#include <compiler/statement/block_statement.h>
#include <compiler/statement/exp_statement.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/statement_list.h>
#include "hphp/parser/hphp.tab.hpp"
#include <util/parser/hphp.tab.hpp>
using namespace HPHP;
using std::vector;
@@ -74,10 +74,10 @@ void RefDict::visit(ExpressionPtr e) {
SimpleVariablePtr ptr(static_pointer_cast<SimpleVariable>(e));
if (ptr->isSuperGlobal() || ptr->isThis()) {
// don't both recording for super globals or this
// don't both recording for super globals or this
return;
}
// Good to go
if (m_am.insertForDict(e)) {
record(e);
@@ -129,7 +129,7 @@ void RefDict::updateParams() {
bool isRef;
if (sym->isParameter()) {
ExpressionListPtr methodParams = m_method_stmt->getParams();
ExpressionPtr paramExprPtr =
ExpressionPtr paramExprPtr =
(*methodParams)[sym->getParameterIndex()];
paramType = paramExprPtr->getType();
isRef = m_method_stmt->isRef(sym->getParameterIndex());
@@ -160,7 +160,7 @@ void RefDict::updateParams() {
void RefDict::updateAccess(ExpressionPtr e) {
always_assert(!e->getScope()->inPseudoMain());
int eid = e->getCanonID();
int context = e->getContext();
@@ -204,7 +204,7 @@ void RefDict::updateAccess(ExpressionPtr e) {
context & Expression::UnsetContext) {
BitOps::set_bit(eid, m_referenced, false);
BitOps::set_bit(eid, m_killed, true);
}
}
if (first_pass) return;
@@ -215,7 +215,7 @@ void RefDict::updateAccess(ExpressionPtr e) {
// we dealt with this node as a store expression
return;
}
int cls = e->getExprClass();
bool isRhsNeeded = false;
@@ -227,7 +227,7 @@ void RefDict::updateAccess(ExpressionPtr e) {
if (cls & Expression::Store) {
// we care about two cases here
switch (e->getKindOf()) {
case Expression::KindOfAssignmentExpression:
case Expression::KindOfAssignmentExpression:
// $x = ...
{
AssignmentExpressionPtr assign(
@@ -254,7 +254,7 @@ void RefDict::updateAccess(ExpressionPtr e) {
break;
}
}
bool isLhsSimpleVar = false;
bool isLhsDynamic = false;
bool isRefd = false;
@@ -343,20 +343,20 @@ void RefDict::updateAccess(ExpressionPtr e) {
// unset($x);
BitOps::set_bit(eid, m_obj, false);
BitOps::set_bit(eid, m_noobj, true);
} else if (isRefd ||
} else if (isRefd ||
((context & Expression::Declaration) == Expression::Declaration)) {
// if a simple variable has isRefd, then we need to mark it
// as potentially containing an object.
// also, if the simple variable is in global context
// also, if the simple variable is in global context
// then we also mark it as potentially containing an object
BitOps::set_bit(eid, m_obj, true);
BitOps::set_bit(eid, m_noobj, false);
}
}
}
if (isRefd) {
// do a scan for every simple variable referenced value
// in the dictionary and mark it as potentially
// do a scan for every simple variable referenced value
// in the dictionary and mark it as potentially
// containing an object (in the bit vector)
for (int i = size(); i--; ) {
if (ExpressionPtr e = get(i)) {
@@ -372,8 +372,8 @@ void RefDict::updateAccess(ExpressionPtr e) {
}
int RefDictWalker::after(ConstructRawPtr cp) {
if (SimpleVariableRawPtr s =
dynamic_pointer_cast<SimpleVariable>(cp)) {
if (SimpleVariableRawPtr s =
boost::dynamic_pointer_cast<SimpleVariable>(cp)) {
if (int id = s->getCanonID()) {
if (first_pass) {
if (s->isAvailable() && m_block->getBit(DataFlow::PRefIn, id)) {
+7 -7
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,17 +14,17 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_REF_DICT_H_
#define incl_HPHP_REF_DICT_H_
#ifndef __REF_DICT_H__
#define __REF_DICT_H__
#include "hphp/compiler/analysis/dictionary.h"
#include <compiler/analysis/dictionary.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
class RefDict : public Dictionary {
public:
explicit RefDict(AliasManager &am) : Dictionary(am), first_pass(true) {}
RefDict(AliasManager &am) : Dictionary(am), first_pass(true) {}
/* Building the dictionary */
void build(MethodStatementPtr m);
@@ -52,7 +52,7 @@ private:
class RefDictWalker : public ControlFlowGraphWalker {
public:
explicit RefDictWalker(ControlFlowGraph *g) :
RefDictWalker(ControlFlowGraph *g) :
ControlFlowGraphWalker(g), first_pass(true) {}
void walk() { ControlFlowGraphWalker::walk(*this); }
int after(ConstructRawPtr cp);
@@ -63,4 +63,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_REF_DICT_H_
#endif // __REF_DICT_H__
+47 -35
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,24 +14,23 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/symbol_table.h"
#include "hphp/compiler/analysis/type.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
#include <compiler/analysis/symbol_table.h>
#include <compiler/analysis/type.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/function_scope.h>
#include "hphp/compiler/expression/assignment_expression.h"
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/parameter_expression.h"
#include "hphp/compiler/expression/simple_variable.h"
#include <compiler/expression/constant_expression.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/parameter_expression.h>
#include <compiler/expression/simple_variable.h>
#include "hphp/runtime/base/class-info.h"
#include "hphp/runtime/base/complex-types.h"
#include "hphp/runtime/base/variable-serializer.h"
#include <runtime/base/class_info.h>
#include <runtime/base/complex_types.h>
#include <runtime/base/variable_serializer.h>
#include "hphp/util/logger.h"
#include <util/logger.h>
using namespace HPHP;
@@ -65,13 +64,13 @@ TypePtr Symbol::setType(AnalysisResultConstPtr ar, BlockScopeRawPtr scope,
// at this point, you *must* have a lock (if you are user scope)
if (scope->is(BlockScope::FunctionScope)) {
FunctionScopeRawPtr f =
static_pointer_cast<FunctionScope>(scope);
boost::static_pointer_cast<FunctionScope>(scope);
if (f->isUserFunction()) {
f->getInferTypesMutex().assertOwnedBySelf();
}
} else if (scope->is(BlockScope::ClassScope)) {
ClassScopeRawPtr c =
static_pointer_cast<ClassScope>(scope);
boost::static_pointer_cast<ClassScope>(scope);
if (c->isUserClass()) {
c->getInferTypesMutex().assertOwnedBySelf();
}
@@ -285,9 +284,9 @@ void Symbol::serializeParam(JSON::DocTarget::OutputStream &out) const {
assert(valueExp);
const string &init = ExtractInitializer(out.analysisResult(), valueExp);
if (!init.empty()) out << init;
else out << JSON::Null();
else out << JSON::Null;
} else {
out << JSON::Null();
out << JSON::Null;
}
ms.done();
@@ -296,18 +295,20 @@ void Symbol::serializeParam(JSON::DocTarget::OutputStream &out) const {
static inline std::string ExtractDocComment(ExpressionPtr e) {
if (!e) return "";
switch (e->getKindOf()) {
case Expression::KindOfAssignmentExpression: {
AssignmentExpressionPtr ae(static_pointer_cast<AssignmentExpression>(e));
return ExtractDocComment(ae->getVariable());
}
case Expression::KindOfSimpleVariable: {
SimpleVariablePtr sv(static_pointer_cast<SimpleVariable>(e));
return sv->getDocComment();
}
case Expression::KindOfConstantExpression: {
ConstantExpressionPtr ce(static_pointer_cast<ConstantExpression>(e));
return ce->getDocComment();
}
case Expression::KindOfAssignmentExpression:
return ExtractDocComment(e->getNthExpr(0));
case Expression::KindOfSimpleVariable:
{
SimpleVariablePtr sv(
static_pointer_cast<SimpleVariable>(e));
return sv->getDocComment();
}
case Expression::KindOfConstantExpression:
{
ConstantExpressionPtr ce(
static_pointer_cast<ConstantExpression>(e));
return ce->getDocComment();
}
default: return "";
}
return "";
@@ -336,9 +337,9 @@ void Symbol::serializeClassVar(JSON::DocTarget::OutputStream &out) const {
assert(initExp);
const string &init = ExtractInitializer(out.analysisResult(), initExp);
if (!init.empty()) out << init;
else out << JSON::Null();
else out << JSON::Null;
} else {
out << JSON::Null();
out << JSON::Null;
}
const string &docs = ExtractDocComment(
@@ -520,6 +521,17 @@ ConstructPtr SymbolTable::getValue(const std::string &name) const {
return ConstructPtr();
}
void SymbolTable::setSepExtension(const std::string &name) {
genSymbol(name, m_const)->setSep();
}
bool SymbolTable::isSepExtension(const std::string &name) const {
if (const Symbol *sym = getSymbol(name)) {
return sym->isSep();
}
return false;
}
TypePtr SymbolTable::setType(AnalysisResultConstPtr ar, const std::string &name,
TypePtr type, bool coerced) {
return setType(ar, genSymbol(name, m_const), type, coerced);
@@ -584,7 +596,7 @@ void SymbolTable::countTypes(std::map<std::string, int> &counts) {
}
string SymbolTable::getEscapedText(Variant v, int &len) {
VariableSerializer vs(VariableSerializer::Type::Serialize);
VariableSerializer vs(VariableSerializer::Serialize);
String str = vs.serialize(v, true);
len = str.length();
string output = Util::escapeStringForCPP(str.data(), len);
+28 -17
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,13 +14,13 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_SYMBOL_TABLE_H_
#define incl_HPHP_SYMBOL_TABLE_H_
#ifndef __SYMBOL_TABLE_H__
#define __SYMBOL_TABLE_H__
#include "hphp/compiler/hphp.h"
#include "hphp/util/json.h"
#include "hphp/util/util.h"
#include "hphp/util/lock.h"
#include <compiler/hphp.h>
#include <util/json.h>
#include <util/util.h>
#include <util/lock.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -74,7 +74,9 @@ public:
void setReplaced() { m_flags.m_replaced = true; }
bool valueSet() const { return m_flags.m_value_set; }
bool isSystem() const { return m_flags.m_system; }
bool isSep() const { return m_flags.m_sep; }
void setSystem() { m_flags.m_system = true; }
void setSep() { m_flags.m_sep = true; }
bool isConstant() const { return m_flags.m_constant; }
void setConstant() { m_flags.m_constant = true; }
@@ -113,6 +115,8 @@ public:
bool isIndirectAltered() const { return m_flags.m_indirectAltered; }
bool isReferenced() const { return !m_flags.m_notReferenced; }
bool isHidden() const { return m_flags.m_hidden; }
bool isGeneratorParameter() const { return m_flags.m_generatorParameter; }
bool isRefGeneratorParameter() const { return m_flags.m_refGeneratorParameter; }
bool isClosureVar() const { return m_flags.m_closureVar; }
bool isRefClosureVar() const { return m_flags.m_refClosureVar; }
bool isPassClosureVar() const { return m_flags.m_passClosureVar; }
@@ -138,6 +142,8 @@ public:
void setIndirectAltered() { m_flags.m_indirectAltered = true; }
void setReferenced() { m_flags.m_notReferenced = false; }
void setHidden() { m_flags.m_hidden = true; }
void setGeneratorParameter() { m_flags.m_generatorParameter = true; }
void setRefGeneratorParameter() { m_flags.m_refGeneratorParameter = true; }
void setClosureVar() { m_flags.m_closureVar = true; }
void setRefClosureVar() { m_flags.m_refClosureVar = true; }
void setPassClosureVar() { m_flags.m_passClosureVar = true; }
@@ -183,7 +189,7 @@ private:
std::string m_name;
unsigned int m_hash;
union {
uint32_t m_flags_val;
uint64_t m_flags_val;
struct {
/* internal */
unsigned m_declaration_set : 1;
@@ -194,6 +200,7 @@ private:
/* common */
unsigned m_system : 1;
unsigned m_sep : 1;
/* ConstantTable */
unsigned m_dynamic : 1;
@@ -216,6 +223,8 @@ private:
unsigned m_indirectAltered : 1;
unsigned m_notReferenced : 1;
unsigned m_hidden : 1;
unsigned m_generatorParameter : 1;
unsigned m_refGeneratorParameter : 1;
unsigned m_closureVar : 1;
unsigned m_refClosureVar : 1;
unsigned m_passClosureVar : 1;
@@ -225,12 +234,10 @@ private:
unsigned m_reseated : 1;
} m_flags;
static_assert(
sizeof(m_flags_val) == sizeof(m_flags),
"m_flags_val must cover all the flags");
};
static_assert(
sizeof(m_flags_val) == sizeof(m_flags),
"m_flags_val must cover all the flags");
ConstructPtr m_declaration;
ConstructPtr m_value;
TypePtr m_coerced;
@@ -247,7 +254,7 @@ private:
class SymParamWrapper : public JSON::DocTarget::ISerializable {
public:
explicit SymParamWrapper(const Symbol* sym) : m_sym(sym) {
SymParamWrapper(const Symbol* sym) : m_sym(sym) {
assert(sym);
}
virtual void serialize(JSON::DocTarget::OutputStream &out) const {
@@ -259,7 +266,7 @@ private:
class SymClassVarWrapper : public JSON::DocTarget::ISerializable {
public:
explicit SymClassVarWrapper(const Symbol* sym) : m_sym(sym) {
SymClassVarWrapper(const Symbol* sym) : m_sym(sym) {
assert(sym);
}
virtual void serialize(JSON::DocTarget::OutputStream &out) const {
@@ -272,7 +279,7 @@ private:
/**
* Base class of VariableTable and ConstantTable.
*/
class SymbolTable : public std::enable_shared_from_this<SymbolTable>,
class SymbolTable : public boost::enable_shared_from_this<SymbolTable>,
public JSON::CodeError::ISerializable {
public:
static Mutex AllSymbolTablesMutex;
@@ -338,6 +345,10 @@ public:
ConstructPtr getDeclaration(const std::string &name) const;
ConstructPtr getValue(const std::string &name) const;
/* Whether this constant is brought in by a separable extension */
void setSepExtension(const std::string &name);
bool isSepExtension(const std::string &name) const;
/**
* How big of a hash table for generate C++ switch statements.
*/
@@ -381,4 +392,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_SYMBOL_TABLE_H_
#endif // __SYMBOL_TABLE_H__
+26 -66
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,13 +14,12 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/type.h"
#include "hphp/compiler/code_generator.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/expression/expression.h"
#include "hphp/runtime/base/builtin-functions.h"
#include <compiler/analysis/type.h>
#include <compiler/code_generator.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/expression/expression.h>
#include <boost/format.hpp>
using namespace HPHP;
@@ -36,7 +35,6 @@ TypePtr Type::Double (new Type(Type::KindOfDouble ));
TypePtr Type::String (new Type(Type::KindOfString ));
TypePtr Type::Array (new Type(Type::KindOfArray ));
TypePtr Type::Object (new Type(Type::KindOfObject ));
TypePtr Type::Resource (new Type(Type::KindOfResource ));
TypePtr Type::Variant (new Type(Type::KindOfVariant ));
TypePtr Type::Numeric (new Type(Type::KindOfNumeric ));
@@ -51,63 +49,38 @@ TypePtr Type::Any (new Type(Type::KindOfAny ));
TypePtr Type::Some (new Type(Type::KindOfSome ));
Type::TypePtrMap Type::s_TypeHintTypes;
Type::TypePtrMap Type::s_HHTypeHintTypes;
void Type::InitTypeHintMap() {
assert(s_TypeHintTypes.empty());
assert(s_HHTypeHintTypes.empty());
s_TypeHintTypes["array"] = Type::Array;
s_TypeHintTypes["resource"] = Type::Resource;
s_TypeHintTypes["callable"] = Type::Variant;
s_HHTypeHintTypes["array"] = Type::Array;
s_HHTypeHintTypes["bool"] = Type::Boolean;
s_HHTypeHintTypes["boolean"] = Type::Boolean;
s_HHTypeHintTypes["int"] = Type::Int64;
s_HHTypeHintTypes["integer"] = Type::Int64;
s_HHTypeHintTypes["real"] = Type::Double;
s_HHTypeHintTypes["double"] = Type::Double;
s_HHTypeHintTypes["float"] = Type::Double;
s_HHTypeHintTypes["string"] = Type::String;
s_HHTypeHintTypes["resource"] = Type::Resource;
s_HHTypeHintTypes["callable"] = Type::Variant;
if (Option::EnableHipHopSyntax) {
s_TypeHintTypes["bool"] = Type::Boolean;
s_TypeHintTypes["boolean"] = Type::Boolean;
s_TypeHintTypes["int"] = Type::Int64;
s_TypeHintTypes["integer"] = Type::Int64;
s_TypeHintTypes["real"] = Type::Double;
s_TypeHintTypes["double"] = Type::Double;
s_TypeHintTypes["float"] = Type::Double;
s_TypeHintTypes["string"] = Type::String;
}
}
const Type::TypePtrMap &Type::GetTypeHintTypes(bool hhType) {
return hhType ? s_HHTypeHintTypes : s_TypeHintTypes;
const Type::TypePtrMap &Type::GetTypeHintTypes() {
return s_TypeHintTypes;
}
void Type::ResetTypeHintTypes() {
s_TypeHintTypes.clear();
s_HHTypeHintTypes.clear();
}
TypePtr Type::CreateObjectType(const std::string &clsname) {
// For interfaces that support primitive types, we're pessimistic and
// we treat it as a Variant
if (interface_supports_array(clsname) ||
interface_supports_string(clsname) ||
interface_supports_int(clsname) ||
interface_supports_double(clsname)) {
return Type::Variant;
}
return TypePtr(new Type(KindOfObject, clsname));
TypePtr Type::CreateObjectType(const std::string &classname) {
return TypePtr(new Type(KindOfObject, classname));
}
TypePtr Type::GetType(KindOf kindOf, const std::string &clsname /* = "" */) {
TypePtr Type::GetType(KindOf kindOf,
const std::string &clsname /* = "" */) {
assert(kindOf);
if (!clsname.empty()) {
// For interfaces that support primitive types we're pessimistic and
// we treat it as a Variant
if (interface_supports_array(clsname) ||
interface_supports_string(clsname) ||
interface_supports_int(clsname) ||
interface_supports_double(clsname)) {
return Type::Variant;
}
return TypePtr(new Type(kindOf, clsname));
}
if (!clsname.empty()) return TypePtr(new Type(kindOf, clsname));
switch (kindOf) {
case KindOfBoolean: return Type::Boolean;
@@ -118,7 +91,6 @@ TypePtr Type::GetType(KindOf kindOf, const std::string &clsname /* = "" */) {
case KindOfArray: return Type::Array;
case KindOfVariant: return Type::Variant;
case KindOfObject: return Type::Object;
case KindOfResource: return Type::Resource;
case KindOfNumeric: return Type::Numeric;
case KindOfPrimitive: return Type::Primitive;
case KindOfPlusOperand: return Type::PlusOperand;
@@ -205,7 +177,6 @@ bool Type::IsMappedToVariant(TypePtr t) {
case KindOfString :
case KindOfArray :
case KindOfObject :
case KindOfResource:
return false;
default: break;
}
@@ -274,8 +245,7 @@ TypePtr Type::Coerce(AnalysisResultConstPtr ar, TypePtr type1, TypePtr type2) {
if (type1->m_kindOf == KindOfVoid &&
(type2->m_kindOf == KindOfString ||
type2->m_kindOf == KindOfArray ||
type2->m_kindOf == KindOfObject ||
type2->m_kindOf == KindOfResource)) {
type2->m_kindOf == KindOfObject)) {
return type2;
}
if (type2->m_kindOf == KindOfSome ||
@@ -410,7 +380,6 @@ bool Type::HasFastCastMethod(TypePtr t) {
case Type::KindOfString:
case Type::KindOfArray:
case Type::KindOfObject:
case Type::KindOfResource:
return true;
default: break;
}
@@ -456,9 +425,6 @@ string Type::GetFastCastMethod(
case Type::KindOfObject:
type = "Obj";
break;
case Type::KindOfResource:
type = "Res";
break;
default:
type = ""; // make the compiler happy
assert(false);
@@ -554,13 +520,11 @@ bool Type::isSpecificObject() const {
}
bool Type::isNonConvertibleType() const {
return m_kindOf == KindOfObject || m_kindOf == KindOfResource ||
m_kindOf == KindOfArray;
return m_kindOf == KindOfObject || m_kindOf == KindOfArray;
}
bool Type::isNoObjectInvolved() const {
if (couldBe(KindOfObject)
|| couldBe(KindOfResource)
|| couldBe(KindOfArray))
return false;
else
@@ -634,7 +598,6 @@ DataType Type::getDataType() const {
case KindOfString: return HPHP::KindOfString;
case KindOfArray: return HPHP::KindOfArray;
case KindOfObject: return HPHP::KindOfObject;
case KindOfResource: return HPHP::KindOfResource;
case KindOfNumeric:
case KindOfPrimitive:
case KindOfPlusOperand:
@@ -656,7 +619,6 @@ std::string Type::getPHPName() {
switch (m_kindOf) {
case KindOfArray: return "array";
case KindOfObject: return m_name;
case KindOfResource: return "resource";
default: break;
}
return "";
@@ -674,7 +636,6 @@ std::string Type::toString() const {
case KindOfSome: return "Some";
case KindOfAny: return "Any";
case KindOfObject: return string("Object - ") + m_name;
case KindOfResource: return "Resource";
case KindOfNumeric: return "Numeric";
case KindOfPrimitive: return "Primitive";
case KindOfPlusOperand: return "PlusOperand";
@@ -723,7 +684,6 @@ void Type::serialize(JSON::DocTarget::OutputStream &out) const {
}
break;
}
case KindOfResource: s = "resource"; break;
case KindOfNumeric: s = "numeric"; break;
case KindOfPrimitive: s = "primitive"; break;
case KindOfPlusOperand: s = "any"; break;
+10 -13
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,13 +14,13 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_TYPE_H_
#define incl_HPHP_TYPE_H_
#ifndef __TYPE_H__
#define __TYPE_H__
#include "hphp/compiler/hphp.h"
#include "hphp/util/json.h"
#include "hphp/util/case-insensitive.h"
#include "hphp/runtime/base/types.h"
#include <compiler/hphp.h>
#include <util/json.h>
#include <util/case_insensitive.h>
#include <runtime/base/types.h>
class TestCodeRun;
@@ -53,7 +53,6 @@ public:
static const KindOf KindOfString = 0x0080;
static const KindOf KindOfArray = 0x0100;
static const KindOf KindOfObject = 0x0200; // with classname
static const KindOf KindOfResource = 0x0400;
static const KindOf KindOfVariant = 0xFFFF;
/* This bit tells coerce that if the other type
@@ -89,7 +88,6 @@ public:
static TypePtr String;
static TypePtr Array;
static TypePtr Object;
static TypePtr Resource;
static TypePtr Variant;
static TypePtr Numeric;
@@ -104,7 +102,7 @@ public:
static TypePtr Some;
typedef hphp_string_imap<TypePtr> TypePtrMap;
static const TypePtrMap &GetTypeHintTypes(bool hhType);
static const TypePtrMap &GetTypeHintTypes();
/**
* Uncertain types: types that are ambiguous yet.
@@ -203,7 +201,7 @@ public:
/**
* KindOf testing.
*/
explicit Type(KindOf kindOf);
Type(KindOf kindOf);
bool is(KindOf kindOf) const { return m_kindOf == kindOf;}
bool isExactType() const { return IsExactType(m_kindOf); }
bool mustBe(KindOf kindOf) const { return !(m_kindOf & ~kindOf); }
@@ -269,7 +267,6 @@ private:
static void ResetTypeHintTypes();
static TypePtrMap s_TypeHintTypes;
static TypePtrMap s_HHTypeHintTypes;
const KindOf m_kindOf;
const std::string m_name;
@@ -277,4 +274,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_TYPE_H_
#endif // __TYPE_H__
+34 -46
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,25 +14,24 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/type.h"
#include "hphp/compiler/code_generator.h"
#include "hphp/compiler/expression/modifier_expression.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/builtin_symbols.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/expression/parameter_expression.h"
#include "hphp/compiler/expression/static_member_expression.h"
#include "hphp/runtime/base/class-info.h"
#include "hphp/util/util.h"
#include "hphp/parser/location.h"
#include "hphp/parser/parser.h"
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/type.h>
#include <compiler/code_generator.h>
#include <compiler/expression/modifier_expression.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/expression/simple_variable.h>
#include <compiler/builtin_symbols.h>
#include <compiler/option.h>
#include <compiler/expression/simple_function_call.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/expression/static_member_expression.h>
#include <runtime/base/class_info.h>
#include <util/util.h>
#include <util/parser/location.h>
#include <util/parser/parser.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -69,31 +68,20 @@ VariableTable::VariableTable(BlockScope &blockScope)
void VariableTable::getLocalVariableNames(vector<string> &syms) const {
FunctionScopeRawPtr fs = getScopePtr()->getContainingFunction();
bool dollarThisIsSpecial = fs->getContainingClass() ||
fs->inPseudoMain() ||
// In closures, $this is "sometimes"
// special (if it's a closure in a method
// body), but it easiest to just always
// treat it special.
fs->isClosure();
bool dollarThisIsSpecial = (fs->getContainingClass() ||
fs->inPseudoMain());
bool hadThisSym = false;
for (unsigned int i = 0; i < m_symbolVec.size(); i++) {
const string& name = m_symbolVec[i]->getName();
if (name == "this" && dollarThisIsSpecial) {
/*
* The "this" variable in methods, pseudo-main, or closures is
* special and is handled separately below.
*
* Closures are the specialest.
*/
hadThisSym = true;
// The "this" variable in methods and pseudo-main is special and is
// handled separately below.
continue;
}
syms.push_back(name);
}
if (fs->needsLocalThis() || (hadThisSym && fs->isClosure())) {
if (fs->needsLocalThis()) {
assert(dollarThisIsSpecial);
// We only need a local variable named "this" if the current function
// contains an occurrence of "$this" that is not part of a property
@@ -237,7 +225,7 @@ ConstructPtr VariableTable::getStaticInitVal(string varName) {
bool VariableTable::setStaticInitVal(string varName,
ConstructPtr value) {
Symbol *sym = addSymbol(varName);
bool exists = (sym->getStaticInitVal() != nullptr);
bool exists = sym->getStaticInitVal();
sym->setStaticInitVal(value);
return exists;
}
@@ -251,7 +239,7 @@ ConstructPtr VariableTable::getClassInitVal(string varName) {
bool VariableTable::setClassInitVal(string varName, ConstructPtr value) {
Symbol *sym = addSymbol(varName);
bool exists = (sym->getClassInitVal() != nullptr);
bool exists = sym->getClassInitVal();
sym->setClassInitVal(value);
return exists;
}
@@ -302,7 +290,8 @@ void VariableTable::addStaticVariable(Symbol *sym,
m_hasStatic = true;
FunctionScopeRawPtr funcScope = getFunctionScope();
if (funcScope && funcScope->isClosure()) {
if (funcScope &&
(funcScope->isClosure() || funcScope->isGeneratorFromClosure())) {
// static variables for closures/closure generators are local to the
// function scope
m_staticLocalsVec.push_back(sym);
@@ -426,12 +415,7 @@ TypePtr VariableTable::add(Symbol *sym, TypePtr type,
}
type = setType(ar, sym, type, true);
if (sym->isParameter()) {
auto p = dynamic_pointer_cast<ParameterExpression>(construct);
if (p) sym->setDeclaration(construct);
} else {
sym->setDeclaration(construct);
}
sym->setDeclaration(construct);
if (!implicit && m_blockScope.isFirstPass()) {
if (!sym->getValue()) {
@@ -583,6 +567,10 @@ void VariableTable::clearUsed() {
} else {
sym.second.setReferenced();
}
if (sym.second.isRefGeneratorParameter()) {
sym.second.setReferenced();
}
}
}
@@ -754,7 +742,7 @@ static bool by_location(const VariableTable::StaticGlobalInfoPtr &p1,
const VariableTable::StaticGlobalInfoPtr &p2) {
ConstructRawPtr d1 = p1->sym->getDeclaration();
ConstructRawPtr d2 = p2->sym->getDeclaration();
if (!d1) return !!d2;
if (!d1) return d2;
if (!d2) return false;
return d1->getLocation()->compare(d2->getLocation().get()) < 0;
}
+8 -8
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,12 +14,12 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_VARIABLE_TABLE_H_
#define incl_HPHP_VARIABLE_TABLE_H_
#ifndef __VARIABLE_TABLE_H__
#define __VARIABLE_TABLE_H__
#include "hphp/compiler/analysis/symbol_table.h"
#include "hphp/compiler/statement/statement.h"
#include "hphp/compiler/analysis/class_scope.h"
#include <compiler/analysis/symbol_table.h>
#include <compiler/statement/statement.h>
#include <compiler/analysis/class_scope.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -100,7 +100,7 @@ public:
}
public:
explicit VariableTable(BlockScope &blockScope);
VariableTable(BlockScope &blockScope);
/**
* Get/set attributes.
@@ -353,4 +353,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_VARIABLE_TABLE_H_
#endif // __VARIABLE_TABLE_H__
+414 -313
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,27 +14,24 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/builtin_symbols.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/statement/statement_list.h"
#include "hphp/compiler/analysis/type.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/expression/modifier_expression.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/runtime/base/class-info.h"
#include "hphp/runtime/base/program-functions.h"
#include "hphp/runtime/base/array-iterator.h"
#include "hphp/runtime/base/execution-context.h"
#include "hphp/runtime/base/thread-init-fini.h"
#include "hphp/util/logger.h"
#include "hphp/util/util.h"
#include <compiler/builtin_symbols.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/statement/statement_list.h>
#include <compiler/analysis/type.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/expression/modifier_expression.h>
#include <compiler/option.h>
#include <compiler/parser/parser.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/constant_table.h>
#include <util/parser/hphp.tab.hpp>
#include <runtime/base/class_info.h>
#include <runtime/base/program_functions.h>
#include <runtime/base/array/array_iterator.h>
#include <util/logger.h>
#include <util/util.h>
#include <dlfcn.h>
using namespace HPHP;
@@ -49,8 +46,38 @@ using namespace HPHP;
///////////////////////////////////////////////////////////////////////////////
bool BuiltinSymbols::Loaded = false;
bool BuiltinSymbols::NoSuperGlobals = false;
StringBag BuiltinSymbols::s_strings;
namespace HPHP {
#define EXT_TYPE 4
#include <system/ext.inc>
#undef EXT_TYPE
}
const char *BuiltinSymbols::ExtensionFunctions[] = {
#define S(n) (const char *)n
#define T(t) (const char *)Type::KindOf ## t
#define EXT_TYPE 0
#include <system/ext.inc>
nullptr,
};
#undef EXT_TYPE
const char *BuiltinSymbols::ExtensionConsts[] = {
#define EXT_TYPE 1
#include <system/ext.inc>
nullptr,
};
#undef EXT_TYPE
const char *BuiltinSymbols::ExtensionClasses[] = {
#define EXT_TYPE 2
#include <system/ext.inc>
nullptr,
};
#undef EXT_TYPE
StringToFunctionScopePtrMap BuiltinSymbols::s_functions;
const char *const BuiltinSymbols::GlobalNames[] = {
@@ -73,7 +100,6 @@ const char *BuiltinSymbols::SystemClasses[] = {
"exception",
"arrayaccess",
"iterator",
"collections",
"reflection",
"splobjectstorage",
"directory",
@@ -90,7 +116,6 @@ StringToClassScopePtrMap BuiltinSymbols::s_classes;
VariableTablePtr BuiltinSymbols::s_variables;
ConstantTablePtr BuiltinSymbols::s_constants;
StringToTypePtrMap BuiltinSymbols::s_superGlobals;
AnalysisResultPtr BuiltinSymbols::s_systemAr;
void *BuiltinSymbols::s_handle_main = nullptr;
///////////////////////////////////////////////////////////////////////////////
@@ -100,323 +125,381 @@ int BuiltinSymbols::NumGlobalNames() {
sizeof(BuiltinSymbols::GlobalNames[0]);
}
static TypePtr typePtrFromDataType(DataType dt, TypePtr unknown) {
switch (dt) {
case KindOfNull: return Type::Null;
case KindOfBoolean: return Type::Boolean;
case KindOfInt64: return Type::Int64;
case KindOfDouble: return Type::Double;
case KindOfString: return Type::String;
case KindOfArray: return Type::Array;
case KindOfObject: return Type::Object;
case KindOfResource: return Type::Resource;
case KindOfUnknown:
default:
return unknown;
void BuiltinSymbols::ParseExtFunctions(AnalysisResultPtr ar, const char **p,
bool sep) {
while (*p) {
FunctionScopePtr f = ParseExtFunction(ar, p);
if (sep) {
f->setSepExtension();
}
assert(!s_functions[f->getName()]);
s_functions[f->getName()] = f;
}
}
const StaticString
s_fb_call_user_func_safe("fb_call_user_func_safe"),
s_fb_call_user_func_safe_return("fb_call_user_func_safe_return"),
s_fb_call_user_func_array_safe("fb_call_user_func_array_safe"),
s_is_callable("is_callable"),
s_call_user_func_array("call_user_func_array");
FunctionScopePtr BuiltinSymbols::ImportFunctionScopePtr(AnalysisResultPtr ar,
ClassInfo *cls, ClassInfo::MethodInfo *method) {
int attrs = method->attribute;
bool isMethod = cls != ClassInfo::GetSystem();
FunctionScopePtr f(new FunctionScope(isMethod,
method->name.data(),
attrs & ClassInfo::IsReference));
int reqCount = 0, totalCount = 0;
for(auto it = method->parameters.begin();
it != method->parameters.end(); ++it) {
const ClassInfo::ParameterInfo *pinfo = *it;
if (!pinfo->value || !pinfo->value[0]) {
++reqCount;
void BuiltinSymbols::ParseExtConsts(AnalysisResultPtr ar, const char **p,
bool sep) {
while (*p) {
const char *name = *p++;
TypePtr type = ParseType(p);
s_constants->add(name, type, ExpressionPtr(), ar, ConstructPtr());
if (sep) {
s_constants->setSepExtension(name);
}
++totalCount;
}
f->setParamCounts(ar, reqCount, totalCount);
int idx = 0;
for(auto it = method->parameters.begin();
it != method->parameters.end(); ++it, ++idx) {
const ClassInfo::ParameterInfo *pinfo = *it;
f->setParamName(idx, pinfo->name);
if (pinfo->attribute & ClassInfo::IsReference) {
f->setRefParam(idx);
}
f->setParamType(ar, idx, typePtrFromDataType(pinfo->argType, Type::Any));
if (pinfo->valueLen) {
f->setParamDefault(idx, pinfo->value, pinfo->valueLen,
std::string(pinfo->valueText, pinfo->valueTextLen));
}
}
if (method->returnType != KindOfNull) {
f->setReturnType(ar, typePtrFromDataType(method->returnType,
Type::Variant));
}
f->setClassInfoAttribute(attrs);
f->setDocComment(method->docComment);
if (!isMethod && (attrs & ClassInfo::HasOptFunction)) {
// Legacy optimization functions
if (method->name.same(s_fb_call_user_func_safe) ||
method->name.same(s_fb_call_user_func_safe_return) ||
method->name.same(s_fb_call_user_func_array_safe)) {
f->setOptFunction(hphp_opt_fb_call_user_func);
} else if (method->name.same(s_is_callable)) {
f->setOptFunction(hphp_opt_is_callable);
} else if (method->name.same(s_call_user_func_array)) {
f->setOptFunction(hphp_opt_call_user_func);
}
}
if (isMethod) {
if (attrs & ClassInfo::IsProtected) {
f->addModifier(T_PROTECTED);
} else if (attrs & ClassInfo::IsPrivate) {
f->addModifier(T_PRIVATE);
}
if (attrs & ClassInfo::IsStatic) {
f->addModifier(T_STATIC);
}
}
// This block of code is not needed, if BlockScope directly takes flags.
if (attrs & ClassInfo::MixedVariableArguments) {
f->setVariableArgument(-1);
} else if (attrs & ClassInfo::RefVariableArguments) {
f->setVariableArgument(1);
} else if (attrs & ClassInfo::VariableArguments) {
f->setVariableArgument(0);
}
if (attrs & ClassInfo::NoEffect) {
f->setNoEffect();
}
if (attrs & ClassInfo::FunctionIsFoldable) {
f->setIsFoldable();
}
if (attrs & ClassInfo::ContextSensitive) {
f->setContextSensitive(true);
}
if (attrs & ClassInfo::NeedsActRec) {
f->setNeedsActRec();
}
if ((attrs & ClassInfo::AllowOverride) && !isMethod) {
f->setAllowOverride();
}
FunctionScope::RecordFunctionInfo(f->getName(), f);
return f;
}
void BuiltinSymbols::ImportExtFunctions(AnalysisResultPtr ar,
StringToFunctionScopePtrMap &map,
ClassInfo *cls) {
const ClassInfo::MethodVec &methods = cls->getMethodsVec();
for (auto it = methods.begin(); it != methods.end(); ++it) {
if (((*it)->attribute & ClassInfo::ZendCompat) &&
!Option::EnableZendCompat) {
continue;
}
FunctionScopePtr f = ImportFunctionScopePtr(ar, cls, *it);
assert(!map[f->getName()]);
map[f->getName()] = f;
}
}
void BuiltinSymbols::ImportExtFunctions(AnalysisResultPtr ar,
FunctionScopePtrVec &vec,
ClassInfo *cls) {
const ClassInfo::MethodVec &methods = cls->getMethodsVec();
for (auto it = methods.begin(); it != methods.end(); ++it) {
FunctionScopePtr f = ImportFunctionScopePtr(ar, cls, *it);
vec.push_back(f);
TypePtr BuiltinSymbols::ParseType(const char **&p) {
const char *clsname = nullptr;
Type::KindOf ktype = (Type::KindOf)(long)(*p++);
if (ktype == CLASS_TYPE) {
clsname = *p++;
}
TypePtr type;
if (clsname) {
type = Type::CreateObjectType(clsname);
} else if (ktype != Type::KindOfVoid) {
type = Type::GetType(ktype);
}
return type;
}
void BuiltinSymbols::ImportExtProperties(AnalysisResultPtr ar,
VariableTablePtr dest,
ClassInfo *cls) {
ClassInfo::PropertyVec src = cls->getPropertiesVec();
for (auto it = src.begin(); it != src.end(); ++it) {
ClassInfo::PropertyInfo *pinfo = *it;
int attrs = pinfo->attribute;
ModifierExpressionPtr modifiers(
new ModifierExpression(BlockScopePtr(), LocationPtr()));
if (attrs & ClassInfo::IsPrivate) {
modifiers->add(T_PRIVATE);
} else if (attrs & ClassInfo::IsProtected) {
modifiers->add(T_PROTECTED);
void BuiltinSymbols::ParseExtClasses(AnalysisResultPtr ar, const char **p,
bool sep) {
while (*p) {
// Parse name
const char *cname = *p++;
// Parse parent
const char *cparent = *p++;
if (!cparent) cparent = "";
// Parse list of interfaces
vector<string> ifaces;
while (*p) ifaces.push_back(*p++);
p++;
// Parse methods
FunctionScopePtrVec methods;
while (*p) {
FunctionScopePtr fs = ParseExtFunction(ar, p, true);
if (sep) {
fs->setSepExtension();
}
int flags = (int)(int64_t)(*p++);
if (flags & ClassInfo::IsAbstract) {
fs->addModifier(T_ABSTRACT);
}
int vismod = 0;
if (flags & ClassInfo::IsProtected) {
vismod = T_PROTECTED;
} else if (flags & ClassInfo::IsPrivate) {
vismod = T_PRIVATE;
}
fs->addModifier(vismod);
if (flags & ClassInfo::IsStatic) {
fs->addModifier(T_STATIC);
}
methods.push_back(fs);
}
if (attrs & ClassInfo::IsStatic) {
modifiers->add(T_STATIC);
if (cparent && *cparent && (ifaces.empty() || ifaces[0] != cparent)) {
ifaces.insert(ifaces.begin(), cparent);
}
ClassScopePtr cl(new ClassScope(ar, cname, cparent, ifaces, methods));
for (uint i = 0; i < methods.size(); ++i) {
methods[i]->setOuterScope(cl);
}
p++;
// Parse properties
while (*p) {
int flags = (int)(int64_t)(*p++);
ModifierExpressionPtr modifiers(
new ModifierExpression(BlockScopePtr(), LocationPtr()));
if (flags & ClassInfo::IsProtected) {
modifiers->add(T_PROTECTED);
} else if (flags & ClassInfo::IsPrivate) {
modifiers->add(T_PRIVATE);
}
if (flags & ClassInfo::IsStatic) {
modifiers->add(T_STATIC);
}
const char *name = *p++;
TypePtr type = ParseType(p);
cl->getVariables()->add(name, type, false, ar, ExpressionPtr(), modifiers);
}
p++;
// Parse consts
while (*p) {
const char *name = *p++;
TypePtr type = ParseType(p);
cl->getConstants()->add(name, type, ExpressionPtr(), ar, ConstructPtr());
}
p++;
int flags = (int)(int64_t)(*p++);
cl->setClassInfoAttribute(flags);
if (flags & ClassInfo::HasDocComment) {
cl->setDocComment(*p++);
}
dest->add(pinfo->name.data(),
typePtrFromDataType(pinfo->type, Type::Variant),
false, ar, ExpressionPtr(), modifiers);
}
}
void BuiltinSymbols::ImportExtConstants(AnalysisResultPtr ar,
ConstantTablePtr dest,
ClassInfo *cls) {
ClassInfo::ConstantVec src = cls->getConstantsVec();
for (auto it = src.begin(); it != src.end(); ++it) {
// We make an assumption that if the constant is a callback type
// (e.g. STDIN, STDOUT, STDERR) then it will return an Object.
// And that if it's deferred (SID, PHP_SAPI, etc.) it'll be a String.
ClassInfo::ConstantInfo *cinfo = *it;
dest->add(cinfo->name.data(),
cinfo->isDeferred() ?
(cinfo->isCallback() ? Type::Object : Type::String) :
typePtrFromDataType(cinfo->getValue().getType(), Type::Variant),
ExpressionPtr(), ar, ConstructPtr());
}
}
ClassScopePtr BuiltinSymbols::ImportClassScopePtr(AnalysisResultPtr ar,
ClassInfo *cls) {
FunctionScopePtrVec methods;
ImportExtFunctions(ar, methods, cls);
ClassInfo::InterfaceVec ifaces = cls->getInterfacesVec();
String parent = cls->getParentClass();
std::vector<std::string> stdIfaces;
if (!parent.empty() && (ifaces.empty() || ifaces[0] != parent)) {
stdIfaces.push_back(parent.data());
}
for (auto it = ifaces.begin(); it != ifaces.end(); ++it) {
stdIfaces.push_back(it->data());
}
ClassScopePtr cl(new ClassScope(ar, cls->getName().data(), parent.data(),
stdIfaces, methods));
for (uint i = 0; i < methods.size(); ++i) {
methods[i]->setOuterScope(cl);
}
ImportExtProperties(ar, cl->getVariables(), cls);
ImportExtConstants(ar, cl->getConstants(), cls);
int attrs = cls->getAttribute();
cl->setClassInfoAttribute(attrs);
cl->setDocComment(cls->getDocComment());
cl->setSystem();
return cl;
}
void BuiltinSymbols::ImportExtClasses(AnalysisResultPtr ar) {
const ClassInfo::ClassMap &classes = ClassInfo::GetClassesMap();
for (auto it = classes.begin(); it != classes.end(); ++it) {
const ClassInfo *info = it->second;
if ((info->getAttribute() & ClassInfo::ZendCompat) &&
!Option::EnableZendCompat) {
continue;
cl->setSystem();
if (sep) {
cl->setSepExtension();
}
ClassScopePtr cl = ImportClassScopePtr(ar, it->second);
assert(!s_classes[cl->getName()]);
s_classes[cl->getName()] = cl;
}
}
bool BuiltinSymbols::Load(AnalysisResultPtr ar) {
FunctionScopePtr BuiltinSymbols::ParseExtFunction(AnalysisResultPtr ar,
const char** &p, bool method /* = false */) {
const char *name = *p++;
TypePtr retType = ParseType(p);
bool reference = *p++;
int minParam = -1;
int maxParam = 0;
const char **arg = p;
while (*arg) {
/* name */ arg++;
ParseType(arg);
const char *argDefault = *arg++;
/* const char *argDefaultLen = */ arg++;
/* const char *argDefaultText = */ arg++;
/* bool argReference = */ arg++;
if (argDefault && minParam < 0) {
minParam = maxParam;
}
maxParam++;
}
if (minParam < 0) minParam = maxParam;
FunctionScopePtr f(new FunctionScope(method, name, reference));
f->setParamCounts(ar, minParam, maxParam);
if (retType) {
f->setReturnType(ar, retType);
}
int index = 0;
const char *paramName = nullptr;
while ((paramName = *p++ /* argName */)) {
TypePtr argType = ParseType(p);
const char *argDefault = *p++;
const char *argDefaultLen = *p++;
const char *argDefaultText = *p++;
bool argReference = *p++;
f->setParamName(index, paramName);
if (argReference) f->setRefParam(index);
f->setParamType(ar, index, argType);
if (argDefault) f->setParamDefault(index, argDefault,
(int64_t)argDefaultLen,
argDefaultText);
index++;
}
int flags = (int)(int64_t)(*p++);
f->setClassInfoAttribute(flags);
if (flags & ClassInfo::HasDocComment) {
f->setDocComment(*p++);
}
if (flags & ClassInfo::HasOptFunction) {
f->setOptFunction((FunctionOptPtr)(*p++));
}
// This block of code is not needed, if BlockScope directly takes flags.
if (flags & ClassInfo::MixedVariableArguments) {
f->setVariableArgument(-1);
} else if (flags & ClassInfo::RefVariableArguments) {
f->setVariableArgument(1);
} else if (flags & ClassInfo::VariableArguments) {
f->setVariableArgument(0);
}
if (flags & ClassInfo::NoEffect) {
f->setNoEffect();
}
if (flags & ClassInfo::FunctionIsFoldable) {
f->setIsFoldable();
}
if (flags & ClassInfo::ContextSensitive) {
f->setContextSensitive(true);
}
if (flags & ClassInfo::NeedsActRec) {
f->setNeedsActRec();
}
if ((flags & ClassInfo::IgnoreRedefinition) && !method) {
f->setIgnoreRedefinition();
}
return f;
}
FunctionScopePtr BuiltinSymbols::ParseHelperFunction(AnalysisResultPtr ar,
const char** &p) {
FunctionScopePtr f = ParseExtFunction(ar, p);
f->setHelperFunction();
return f;
}
bool BuiltinSymbols::LoadSepExtensionSymbols(AnalysisResultPtr ar,
const std::string &name,
const std::string &soname) {
string mapname = name + "_map";
const char ***symbols = nullptr;
// If we linked with .a, the symbol is already in main program.
if (s_handle_main == nullptr) {
s_handle_main = dlopen(nullptr, RTLD_NOW | RTLD_GLOBAL);
if (!s_handle_main) {
const char *error = dlerror();
Logger::Error("Unable to load main program's symbols: %s",
error ? error : "(unknown)");
}
}
if (s_handle_main) {
symbols = (const char ***)dlsym(s_handle_main, mapname.c_str());
}
// Otherwise, look for .so to load it.
void *handle = nullptr;
if (!symbols) {
handle = dlopen(soname.c_str(), RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
const char *error = dlerror();
Logger::Error("Unable to load %s: %s", soname.c_str(),
error ? error : "(unknown)");
return false;
}
symbols = (const char ***)dlsym(handle, mapname.c_str());
if (!symbols) {
Logger::Error("Unable to find %s in %s", mapname.c_str(),
soname.c_str());
dlclose(handle);
return false;
}
}
ParseExtFunctions(ar, symbols[0], true);
ParseExtConsts (ar, symbols[1], true);
ParseExtClasses (ar, symbols[2], true);
if (handle) {
/*
Not closing for now, because it may have set an object allocator,
which would then fail next time its used.
I think the object allocators should be fixed instead - one per size,
rather than one per class, then this issue wouldnt occur
*/
// dlclose(handle);
}
return true;
}
void BuiltinSymbols::Parse(AnalysisResultPtr ar,
const std::string& phpBaseName,
const std::string& phpFileName) {
const char *baseName = s_strings.add(phpBaseName.c_str());
const char *fileName = s_strings.add(phpFileName.c_str());
try {
Scanner scanner(fileName, Option::ScannerType);
Compiler::Parser parser(scanner, baseName, ar);
if (!parser.parse()) {
Logger::Error("Unable to parse file %s: %s", fileName,
parser.getMessage().c_str());
assert(false);
}
} catch (FileOpenException &e) {
Logger::Error("%s", e.getMessage().c_str());
}
}
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) {
if (Loaded) return true;
Loaded = true;
if (g_context.isNull()) init_thread_locals();
ClassInfo::Load();
// load extension functions first, so system/php may call them
ImportExtFunctions(ar, s_functions, ClassInfo::GetSystem());
// load extension functions first, so system/classes may call them
ParseExtFunctions(ar, ExtensionFunctions, false);
AnalysisResultPtr ar2 = AnalysisResultPtr(new AnalysisResult());
s_variables = VariableTablePtr(new VariableTable(*ar2.get()));
s_constants = ConstantTablePtr(new ConstantTable(*ar2.get()));
// parse all PHP files under system/classes
if (!extOnly) {
ar = AnalysisResultPtr(new AnalysisResult());
ar->loadBuiltinFunctions();
string slib = systemlib_path();
if (slib.empty()) {
for (const char **cls = SystemClasses; *cls; cls++) {
string phpBaseName = "/system/classes/";
phpBaseName += *cls;
phpBaseName += ".php";
Parse(ar, phpBaseName, Option::GetSystemRoot() + phpBaseName);
}
} else {
Parse(ar, slib, slib);
}
ar->analyzeProgram(true);
ar->inferTypes();
const StringToFileScopePtrMap &files = ar->getAllFiles();
for (StringToFileScopePtrMap::const_iterator iterFile = files.begin();
iterFile != files.end(); iterFile++) {
const StringToClassScopePtrVecMap &classes =
iterFile->second->getClasses();
for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin();
iter != classes.end(); ++iter) {
assert(iter->second.size() == 1);
iter->second[0]->setSystem();
assert(!s_classes[iter->first]);
s_classes[iter->first] = iter->second[0];
}
}
} else {
NoSuperGlobals = true;
}
// load extension constants, classes and dynamics
ImportExtConstants(ar, s_constants, ClassInfo::GetSystem());
ImportExtClasses(ar);
Array constants = ClassInfo::GetSystemConstants();
LocationPtr loc(new Location);
for (ArrayIter it = constants.begin(); it; ++it) {
CVarRef key = it.first();
if (!key.isString()) continue;
std::string name = key.toCStrRef().data();
if (s_constants->getSymbol(name)) continue;
if (name == "true" || name == "false" || name == "null") continue;
CVarRef value = it.secondRef();
if (!value.isInitialized() || value.isObject()) continue;
ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value);
TypePtr t =
value.isNull() ? Type::Null :
value.isBoolean() ? Type::Boolean :
value.isInteger() ? Type::Int64 :
value.isDouble() ? Type::Double :
value.isArray() ? Type::Array : Type::Variant;
s_constants->add(key.toCStrRef().data(), t, e, ar2, e);
}
s_variables = ar2->getVariables();
for (int i = 0, n = NumGlobalNames(); i < n; ++i) {
s_variables->add(GlobalNames[i], Type::Variant, false, ar,
ConstructPtr(), ModifierExpressionPtr());
ParseExtConsts(ar, ExtensionConsts, false);
ParseExtClasses(ar, ExtensionClasses, false);
for (unsigned int i = 0; i < Option::SepExtensions.size(); i++) {
Option::SepExtensionOptions &options = Option::SepExtensions[i];
string soname = options.soname;
if (soname.empty()) {
soname = string("lib") + options.name + ".so";
}
if (!options.lib_path.empty()) {
soname = options.lib_path + "/" + soname;
}
if (!LoadSepExtensionSymbols(ar, options.name, soname)) {
return false;
}
}
s_constants->setDynamic(ar, "PHP_BINARY", true);
s_constants->setDynamic(ar, "PHP_BINDIR", true);
s_constants->setDynamic(ar, "PHP_OS", true);
s_constants->setDynamic(ar, "PHP_SAPI", true);
if (!extOnly) {
Array constants = ClassInfo::GetSystemConstants();
LocationPtr loc(new Location);
for (ArrayIter it = constants.begin(); it; ++it) {
CVarRef key = it.first();
if (!key.isString()) continue;
std::string name = key.toCStrRef().data();
if (s_constants->getSymbol(name)) continue;
if (name == "true" || name == "false" || name == "null") continue;
CVarRef value = it.secondRef();
if (!value.isInitialized() || value.isObject()) continue;
ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value);
TypePtr t =
value.isNull() ? Type::Null :
value.isBoolean() ? Type::Boolean :
value.isInteger() ? Type::Int64 :
value.isDouble() ? Type::Double :
value.isArray() ? Type::Array : Type::Variant;
s_constants->add(key.toCStrRef().data(), t, e, ar2, e);
}
s_variables = ar2->getVariables();
for (int i = 0, n = NumGlobalNames(); i < n; ++i) {
s_variables->add(GlobalNames[i], Type::Variant, false, ar,
ConstructPtr(), ModifierExpressionPtr());
}
}
s_constants->setDynamic(ar, "SID", true);
// parse all PHP files under system/php
s_systemAr = ar = AnalysisResultPtr(new AnalysisResult());
ar->loadBuiltins();
string slib = get_systemlib();
Scanner scanner(slib.c_str(), slib.size(),
Option::GetScannerType(), "systemlib.php");
Compiler::Parser parser(scanner, "systemlib.php", ar);
if (!parser.parse()) {
Logger::Error("Unable to parse systemlib.php: %s",
parser.getMessage().c_str());
assert(false);
}
ar->analyzeProgram(true);
ar->inferTypes();
const StringToFileScopePtrMap &files = ar->getAllFiles();
for (StringToFileScopePtrMap::const_iterator iterFile = files.begin();
iterFile != files.end(); iterFile++) {
const StringToClassScopePtrVecMap &classes =
iterFile->second->getClasses();
for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin();
iter != classes.end(); ++iter) {
assert(iter->second.size() == 1);
iter->second[0]->setSystem();
assert(!s_classes[iter->first]);
s_classes[iter->first] = iter->second[0];
}
const StringToFunctionScopePtrMap &functions =
iterFile->second->getFunctions();
for (StringToFunctionScopePtrMap::const_iterator iter = functions.begin();
iter != functions.end(); ++iter) {
iter->second->setSystem();
s_functions[iter->first] = iter->second;
}
}
return true;
}
@@ -429,7 +512,7 @@ AnalysisResultPtr BuiltinSymbols::LoadGlobalSymbols(const char *fileName) {
fileName = s_strings.add(phpFileName.c_str());
try {
Scanner scanner(fileName, Option::GetScannerType());
Scanner scanner(fileName, Option::ScannerType);
Compiler::Parser parser(scanner, baseName, ar);
if (!parser.parse()) {
assert(false);
@@ -447,13 +530,30 @@ AnalysisResultPtr BuiltinSymbols::LoadGlobalSymbols(const char *fileName) {
void BuiltinSymbols::LoadFunctions(AnalysisResultPtr ar,
StringToFunctionScopePtrMap &functions) {
assert(Loaded);
functions.insert(s_functions.begin(), s_functions.end());
for (StringToFunctionScopePtrMap::const_iterator it = s_functions.begin();
it != s_functions.end(); ++it) {
if (functions.find(it->first) == functions.end()) {
functions[it->first] = it->second;
FunctionScope::RecordFunctionInfo(it->first, it->second);
}
}
}
void BuiltinSymbols::LoadClasses(AnalysisResultPtr ar,
StringToClassScopePtrMap &classes) {
assert(Loaded);
classes.insert(s_classes.begin(), s_classes.end());
// we are adding these builtin functions, so that user-defined functions
// will not overwrite them with their own file and line number information
for (StringToClassScopePtrMap::const_iterator iter =
s_classes.begin(); iter != s_classes.end(); ++iter) {
const StringToFunctionScopePtrMap &funcs = iter->second->getFunctions();
for (StringToFunctionScopePtrMap::const_iterator iter =
funcs.begin(); iter != funcs.end(); ++iter) {
FunctionScope::RecordFunctionInfo(iter->first, iter->second);
}
}
}
void BuiltinSymbols::LoadVariables(AnalysisResultPtr ar,
@@ -496,6 +596,7 @@ void BuiltinSymbols::LoadSuperGlobals() {
}
bool BuiltinSymbols::IsSuperGlobal(const std::string &name) {
if (NoSuperGlobals) return false;
return s_superGlobals.find(name) != s_superGlobals.end();
}
+29 -27
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,12 +14,11 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_BUILTIN_SYMBOLS_H_
#define incl_HPHP_BUILTIN_SYMBOLS_H_
#ifndef __BUILTIN_SYMBOLS_H__
#define __BUILTIN_SYMBOLS_H__
#include "hphp/compiler/hphp.h"
#include "hphp/util/string-bag.h"
#include "hphp/runtime/base/class-info.h"
#include <compiler/hphp.h>
#include <util/string_bag.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -34,8 +33,9 @@ DECLARE_BOOST_TYPES(ConstantTable);
class BuiltinSymbols {
public:
static bool Loaded;
static bool NoSuperGlobals; // for SystemCPP bootstraping only
static bool Load(AnalysisResultPtr ar);
static bool Load(AnalysisResultPtr ar, bool extOnly = false);
static void LoadFunctions(AnalysisResultPtr ar,
StringToFunctionScopePtrMap &functions);
@@ -64,42 +64,44 @@ public:
static StringToClassScopePtrMap s_classes;
static VariableTablePtr s_variables;
static ConstantTablePtr s_constants;
static AnalysisResultPtr s_systemAr;
static const char *const GlobalNames[];
static int NumGlobalNames();
private:
static StringBag s_strings;
static const char *ExtensionFunctions[];
static const char *ExtensionClasses[];
static const char *ExtensionConsts[];
static const char *ExtensionDeclaredDynamic[];
static const char *SystemClasses[];
static AnalysisResultPtr LoadGlobalSymbols(const char *fileName);
static void Parse(AnalysisResultPtr ar,
const std::string& phpBaseName,
const std::string& phpFileName);
static StringToTypePtrMap s_superGlobals;
static std::set<std::string> s_declaredDynamic;
static void *s_handle_main;
static bool LoadSepExtensionSymbols(AnalysisResultPtr ar,
const std::string &name,
const std::string &soname);
static FunctionScopePtr ImportFunctionScopePtr(AnalysisResultPtr ar,
ClassInfo *cls,
ClassInfo::MethodInfo *method);
static void ImportExtFunctions(AnalysisResultPtr ar,
StringToFunctionScopePtrMap &map,
ClassInfo *cls);
static void ImportExtFunctions(AnalysisResultPtr ar,
FunctionScopePtrVec &vec,
ClassInfo *cls);
static void ImportExtProperties(AnalysisResultPtr ar,
VariableTablePtr dest,
ClassInfo *cls);
static void ImportExtConstants(AnalysisResultPtr ar,
ConstantTablePtr dest,
ClassInfo *cls);
static ClassScopePtr ImportClassScopePtr(AnalysisResultPtr ar,
ClassInfo *cls);
static void ImportExtClasses(AnalysisResultPtr ar);
static TypePtr ParseType(const char **&p);
static void ParseExtFunctions(AnalysisResultPtr ar, const char **p,
bool sep);
static void ParseExtConsts(AnalysisResultPtr ar, const char **p, bool sep);
static void ParseExtClasses(AnalysisResultPtr ar, const char **p, bool sep);
static void ParseExtDynamics(AnalysisResultPtr ar, const char **p, bool sep);
static FunctionScopePtr ParseExtFunction(AnalysisResultPtr ar,
const char** &p, bool method = false);
static FunctionScopePtr ParseHelperFunction(AnalysisResultPtr ar,
const char** &p);
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_BUILTIN_SYMBOLS_H_
#endif // __BUILTIN_SYMBOLS_H__
+10 -10
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -16,15 +16,15 @@
#include <stdarg.h>
#include "hphp/compiler/code_generator.h"
#include "hphp/compiler/statement/statement_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/util/util.h"
#include "hphp/util/hash.h"
#include <compiler/code_generator.h>
#include <compiler/statement/statement_list.h>
#include <compiler/option.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/variable_table.h>
#include <util/util.h>
#include <util/hash.h>
#include <boost/format.hpp>
#include <boost/scoped_array.hpp>
+23 -18
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CODE_GENERATOR_H_
#define incl_HPHP_CODE_GENERATOR_H_
#ifndef __CODE_GENERATOR_H__
#define __CODE_GENERATOR_H__
#include "hphp/compiler/hphp.h"
#include <compiler/hphp.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -131,8 +131,8 @@ public:
public:
CodeGenerator() {} // only for creating a dummy code generator
explicit CodeGenerator(std::ostream *primary, Output output = PickledPHP,
const std::string *filename = nullptr);
CodeGenerator(std::ostream *primary, Output output = PickledPHP,
const std::string *filename = nullptr);
/**
* ...if it was passed in from constructor.
@@ -308,23 +308,28 @@ private:
public: void print(const char *msg, bool indent = true);
private:
void print(const char *fmt, va_list ap) ATTRIBUTE_PRINTF(2,0);
void print(const char *fmt, va_list ap);
void printSubstring(const char *start, int length);
void printIndent();
std::string getFormattedName(const std::string &file);
};
#define cg_printf cg.printf
#define m_cg_printf m_cg.printf
#define cg_print cg.print
#define m_cg_print m_cg.print
#define cg_indentBegin cg.indentBegin
#define m_cg_indentBegin m_cg.indentBegin
#define cg_indentEnd cg.indentEnd
#define m_cg_indentEnd cg.indentEnd
#define cg_printInclude cg.printInclude
#define cg_printString cg.printString
#define STR(x) #x
#define XSTR(x) STR(x)
#define FLANN(stream,func,nl) (Option::FlAnnotate ? \
stream.printf("/* %s:" XSTR(__LINE__) "*/" nl, __func__): \
void()), stream.func
#define cg_printf FLANN(cg,printf,"")
#define m_cg_printf FLANN(m_cg,printf,"")
#define cg_print FLANN(cg,print,"")
#define m_cg_print FLANN(m_cg,print,"")
#define cg_indentBegin FLANN(cg,indentBegin,"")
#define m_cg_indentBegin FLANN(m_cg,indentBegin,"")
#define cg_indentEnd FLANN(cg,indentEnd,"")
#define m_cg_indentEnd FLANN(m_cg,indentEnd,"")
#define cg_printInclude FLANN(cg,printInclude,"\n")
#define cg_printString FLANN(cg,printString,"")
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CODE_GENERATOR_H_
#endif // __CODE_GENERATOR_H__
+146 -73
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,45 +14,43 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/compiler.h"
#include "hphp/compiler/package.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/alias_manager.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/emitter.h"
#include "hphp/compiler/analysis/type.h"
#include "hphp/compiler/analysis/symbol_table.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/compiler/builtin_symbols.h"
#include "hphp/util/json.h"
#include "hphp/util/logger.h"
#include "hphp/util/db-conn.h"
#include "hphp/util/exception.h"
#include "hphp/util/process.h"
#include "hphp/util/util.h"
#include "hphp/util/timer.h"
#include "hphp/util/hdf.h"
#include "hphp/util/async-func.h"
#include "hphp/util/current-executable.h"
#include "hphp/runtime/base/program-functions.h"
#include "hphp/runtime/base/externals.h"
#include "hphp/runtime/base/thread-init-fini.h"
#include "hphp/runtime/vm/repo.h"
#include "hphp/system/systemlib.h"
#include "hphp/util/repo-schema.h"
#include "hphp/hhvm/process-init.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <dlfcn.h>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/positional_options.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
#include <compiler/package.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/alias_manager.h>
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/emitter.h>
#include <compiler/analysis/type.h>
#include <util/json.h>
#include <util/logger.h>
#include <compiler/analysis/symbol_table.h>
#include <compiler/option.h>
#include <compiler/parser/parser.h>
#include <compiler/builtin_symbols.h>
#include <util/db_conn.h>
#include <util/exception.h>
#include <util/process.h>
#include <util/util.h>
#include <util/timer.h>
#include <util/hdf.h>
#include <util/async_func.h>
#include <runtime/base/program_functions.h>
#include <runtime/base/memory/smart_allocator.h>
#include <runtime/base/externals.h>
#include <runtime/base/thread_init_fini.h>
#include <runtime/vm/repo.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dlfcn.h>
#include <system/lib/systemlib.h>
#include <compiler/compiler.h>
#include "hhvm/process_init.h"
using namespace boost::program_options;
using std::cout;
@@ -63,6 +61,7 @@ struct CompilerOptions {
string target;
string format;
string outputDir;
string outputFile;
string syncDir;
vector<string> config;
string configDir;
@@ -83,6 +82,8 @@ struct CompilerOptions {
vector<string> cfiles;
vector<string> cmodules;
bool parseOnDemand;
vector<string> parseOnDemandDirs; // parse these directories on-demand
// when parseOnDemand=false
string program;
string programArgs;
string branch;
@@ -91,15 +92,21 @@ struct CompilerOptions {
bool keepTempDir;
string dbStats;
bool noTypeInference;
bool noMinInclude;
bool noMetaInfo;
int logLevel;
bool force;
int clusterCount;
int optimizeLevel;
string filecache;
string javaRoot;
bool dump;
string docjson;
bool coredump;
bool nofork;
bool fl_annotate;
string optimizations;
string ppp;
};
///////////////////////////////////////////////////////////////////////////////
@@ -117,8 +124,7 @@ public:
struct stat sb;
stat(m_name, &sb);
Logger::Info("%" PRId64" MB %s saved",
(int64_t)sb.st_size/(1024*1024), m_name);
Logger::Info("%dMB %s saved", (int64_t)sb.st_size/(1024*1024), m_name);
}
private:
@@ -140,6 +146,7 @@ int hhbcTarget(const CompilerOptions &po, AnalysisResultPtr ar,
AsyncFileCacheSaver &fcThread);
int runTargetCheck(const CompilerOptions &po, AnalysisResultPtr ar,
AsyncFileCacheSaver &fcThread);
int buildTarget(const CompilerOptions &po);
int runTarget(const CompilerOptions &po);
///////////////////////////////////////////////////////////////////////////////
@@ -150,10 +157,6 @@ int compiler_main(int argc, char **argv) {
try {
Hdf empty;
RuntimeOption::Load(empty);
initialize_repo();
// we need to initialize pcre cache table very early
pcre_init();
CompilerOptions po;
#ifdef FACEBOOK
@@ -192,10 +195,6 @@ int compiler_main(int argc, char **argv) {
return ret;
} catch (Exception &e) {
Logger::Error("Exception: %s\n", e.getMessage().c_str());
} catch (const FailedAssertion& fa) {
fa.print();
StackTraceNoHeap::AddExtraLogging("Assertion failure", fa.summary);
abort();
} catch (std::exception &e) {
Logger::Error("std::exception: %s\n", e.what());
} catch (...) {
@@ -227,6 +226,9 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
" <any combination of them by any separator>; \n"
"hhbc: binary (default) | text; \n"
"run: cluster (default) | file")
("cluster-count", value<int>(&po.clusterCount)->default_value(0),
"Cluster by file sizes and output roughly these many number of files. "
"Use 0 for no clustering.")
("input-dir", value<string>(&po.inputDir), "input directory")
("program", value<string>(&po.program)->default_value("program"),
"final program name to use")
@@ -273,6 +275,7 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
("branch", value<string>(&po.branch), "SVN branch")
("revision", value<int>(&po.revision), "SVN revision")
("output-dir,o", value<string>(&po.outputDir), "output directory")
("output-file", value<string>(&po.outputFile), "output file")
("sync-dir", value<string>(&po.syncDir),
"Files will be created in this directory first, then sync with output "
"directory without overwriting identical files. Great for incremental "
@@ -289,6 +292,13 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
("no-type-inference",
value<bool>(&po.noTypeInference)->default_value(false),
"turn off type inference for C++ code generation")
("no-min-include",
value<bool>(&po.noMinInclude)->default_value(false),
"turn off minimium include analysis when target is \"analyze\"")
("no-meta-info",
value<bool>(&po.noMetaInfo)->default_value(false),
"do not generate class map, function jump table and macros "
"when generating code; good for demo purposes")
("config,c", value<vector<string> >(&po.config)->composing(),
"config file name")
("config-dir", value<string>(&po.configDir),
@@ -320,11 +330,22 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
value<bool>(&po.nofork)->default_value(false),
"forking is needed for large compilation to release memory before g++"
"compilation. turning off forking can help gdb debugging.")
("fl-annotate",
value<bool>(&po.fl_annotate)->default_value(false),
"Annotate emitted source with compiler file-line info")
("opts",
value<string>(&po.optimizations)->default_value(""),
"Set optimizations to enable/disable")
("ppp",
value<string>(&po.ppp)->default_value(""),
"Preprocessed partition configuration. To speed up distcc compilation, "
"bin/ppp.php can pre-compute better partition between different .cpp "
"files according to preprocessed file sizes, instead of original file "
"sizes (default). Run bin/ppp.php to generate an HDF configuration file "
"to specify here.")
("compiler-id", "display the git hash for the compiler id")
("repo-schema", "display the repo schema id used by this app")
("taint-status", "check if the compiler was built with taint enabled")
;
positional_options_description p;
@@ -334,7 +355,7 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
store(command_line_parser(argc, argv).options(desc).positional(p).run(),
vm);
notify(vm);
} catch (const unknown_option& e) {
} catch (unknown_option e) {
Logger::Error("Error in command line: %s\n\n", e.what());
cout << desc << "\n";
return -1;
@@ -359,10 +380,10 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
#endif
#define HPHP_VERSION(v) cout << HPHP_COMPILER_STR #v << "\n";
#include "../version" // nolint
#include "../version"
cout << "Compiler: " << kCompilerId << "\n";
cout << "Repo schema: " << kRepoSchemaId << "\n";
cout << "Repo schema: " << VM::Repo::kSchemaId << "\n";
return 1;
}
@@ -372,7 +393,14 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
}
if (vm.count("repo-schema")) {
cout << kRepoSchemaId << "\n";
cout << VM::Repo::kSchemaId << "\n";
return 1;
}
if (vm.count("taint-status")) {
#ifdef TAINTED
cout << TAINTED << "\n";
#endif
return 1;
}
@@ -392,6 +420,8 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
Logger::LogLevel = Logger::LogInfo;
}
Option::FlAnnotate = po.fl_annotate;
Hdf config;
for (vector<string>::const_iterator it = po.config.begin();
it != po.config.end(); ++it) {
@@ -443,11 +473,13 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
(Util::format_pattern(po.excludeStaticPatterns[i], true));
}
Option::OutputHHBC = true;
if (po.target == "hhbc" || po.target == "run") {
Option::AnalyzePerfectVirtuals = false;
}
Option::ProgramName = po.program;
Option::PreprocessedPartitionConfig = po.ppp;
if (po.format.empty()) {
if (po.target == "php") {
@@ -472,7 +504,11 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
}
if (po.optimizeLevel == -1) {
po.optimizeLevel = 1;
if (Option::OutputHHBC) {
po.optimizeLevel = 1;
} else {
po.optimizeLevel = 1;
}
}
// we always do pre/post opt no matter the opt level
@@ -481,7 +517,9 @@ int prepareOptions(CompilerOptions &po, int argc, char **argv) {
if (po.optimizeLevel == 0) {
// --optimize-level=0 is equivalent to --opts=none
po.optimizations = "none";
Option::ParseTimeOpts = false;
if (Option::OutputHHBC) {
Option::ParseTimeOpts = false;
}
}
return 0;
@@ -525,7 +563,9 @@ int process(const CompilerOptions &po) {
Package package(po.inputDir.c_str());
ar = package.getAnalysisResult();
hhbcTargetInit(po, ar);
if (po.target == "hhbc" || po.target == "run") {
hhbcTargetInit(po, ar);
}
std::string errs;
if (!AliasManager::parseOptimizations(po.optimizations, errs)) {
@@ -540,16 +580,18 @@ int process(const CompilerOptions &po) {
bool isPickledPHP = (po.target == "php" && po.format == "pickled");
if (!isPickledPHP) {
if (!BuiltinSymbols::Load(ar,
po.target == "hhbc" && !Option::WholeProgram)) {
return false;
}
if (po.target == "hhbc" && !Option::WholeProgram) {
// We're trying to produce the same bytecode as runtime parsing.
// There's nothing to do.
BuiltinSymbols::NoSuperGlobals = false;
} else {
if (!BuiltinSymbols::Load(ar)) {
return false;
}
ar->loadBuiltins();
}
hphp_process_init();
if (!Option::SystemGen) {
hphp_process_init();
}
}
{
@@ -649,7 +691,7 @@ int process(const CompilerOptions &po) {
int runId = package.saveStatsToDB(server, seconds, po.branch,
po.revision);
package.commitStats(server, runId);
} catch (const DatabaseException& e) {
} catch (DatabaseException e) {
Logger::Error("%s", e.what());
}
} else {
@@ -674,7 +716,7 @@ int lintTarget(const CompilerOptions &po) {
for (unsigned int i = 0; i < po.inputs.size(); i++) {
string filename = po.inputDir + "/" + po.inputs[i];
try {
Scanner scanner(filename.c_str(), Option::GetScannerType());
Scanner scanner(filename.c_str(), Option::ScannerType);
Compiler::Parser parser(scanner, filename.c_str(),
AnalysisResultPtr(new AnalysisResult()));
if (!parser.parse()) {
@@ -804,11 +846,7 @@ void hhbcTargetInit(const CompilerOptions &po, AnalysisResultPtr ar) {
RuntimeOption::RepoDebugInfo = Option::RepoDebugInfo;
RuntimeOption::RepoJournal = "memory";
RuntimeOption::EnableHipHopSyntax = Option::EnableHipHopSyntax;
RuntimeOption::EnableZendCompat = Option::EnableZendCompat;
RuntimeOption::EvalJitEnableRenameFunction = Option::JitEnableRenameFunction;
// Turn off commits, because we don't want systemlib to get included
RuntimeOption::RepoCommit = false;
}
int hhbcTarget(const CompilerOptions &po, AnalysisResultPtr ar,
@@ -840,7 +878,7 @@ int hhbcTarget(const CompilerOptions &po, AnalysisResultPtr ar,
/* without this, emitClass allows classes with interfaces to be
hoistable */
SystemLib::s_inited = true;
RuntimeOption::RepoCommit = true;
Option::AutoInline = -1;
if (po.optimizeLevel > 0) {
@@ -867,11 +905,11 @@ int hhbcTarget(const CompilerOptions &po, AnalysisResultPtr ar,
*/
string exe = po.outputDir + '/' + po.program;
string repo = "repo=" + exe + ".hhbc";
string buf = current_executable_path();
if (buf.empty()) return -1;
char buf[PATH_MAX];
if (!realpath("/proc/self/exe", buf)) return -1;
const char *argv[] = { "objcopy", "--add-section", repo.c_str(),
buf.c_str(), exe.c_str(), 0 };
buf, exe.c_str(), 0 };
string out;
ret = Process::Exec(argv[0], argv, nullptr, out, nullptr) ? 0 : 1;
}
@@ -881,6 +919,42 @@ int hhbcTarget(const CompilerOptions &po, AnalysisResultPtr ar,
///////////////////////////////////////////////////////////////////////////////
int buildTarget(const CompilerOptions &po) {
const char *HPHP_HOME = getenv("HPHP_HOME");
if (!HPHP_HOME || !*HPHP_HOME) {
throw Exception("Environment variable HPHP_HOME is not set.");
}
string cmd = string(HPHP_HOME) + "/hphp/legacy/run.sh";
string flags;
if (getenv("RELEASE")) flags += "RELEASE=1 ";
if (getenv("SHOW_LINK")) flags += "SHOW_LINK=1 ";
if (getenv("SHOW_COMPILE")) flags += "SHOW_COMPILE=1 ";
if (po.format == "lib") flags += "HPHP_BUILD_LIBRARY=1 ";
const char *argv[] = {"", po.outputDir.c_str(),
po.program.c_str(), flags.c_str(), nullptr};
if (getenv("SHOW_COMPILE")) {
Logger::Info ("Compile command: %s %s %s", po.outputDir.c_str(),
po.program.c_str(), flags.c_str());
}
Timer timer(Timer::WallTime, "compiling and linking CPP files");
string out, err;
bool ret = Process::Exec(cmd.c_str(), argv, nullptr, out, &err);
if (getenv("SHOW_COMPILE")) {
Logger::Info("%s", out.c_str());
} else {
Logger::Verbose("%s", out.c_str());
}
if (!err.empty()) {
Logger::Error("%s", err.c_str());
}
if (!ret) {
return 1;
}
return 0;
}
int runTargetCheck(const CompilerOptions &po, AnalysisResultPtr ar,
AsyncFileCacheSaver &fcThread) {
// generate code
@@ -910,8 +984,8 @@ int runTarget(const CompilerOptions &po) {
// run the executable
string cmd;
if (po.format.find("exe") == string::npos) {
string buf = current_executable_path();
if (buf.empty()) return -1;
char buf[PATH_MAX];
if (!realpath("/proc/self/exe", buf)) return -1;
cmd += buf;
cmd += " -vRepo.Authoritative=true";
@@ -919,9 +993,8 @@ int runTarget(const CompilerOptions &po) {
}
cmd += po.outputDir + '/' + po.program;
cmd += string(" --file ") +
(po.inputs.size() == 1 ? po.inputs[0] : "") +
" " + po.programArgs;
Logger::Info("running executable: %s", cmd.c_str());
(po.inputs.size() == 1 ? po.inputs[0] : "") + po.programArgs;
Logger::Info("running executable %s...", cmd.c_str());
ret = Util::ssystem(cmd.c_str());
if (ret && ret != -1) ret = 1;
+1 -1
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
+16 -17
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,21 +14,21 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/construct.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/util/util.h"
#include <compiler/construct.h>
#include <compiler/parser/parser.h>
#include <util/util.h>
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include "hphp/compiler/analysis/ast_walker.h"
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/analysis_result.h>
#include <compiler/analysis/ast_walker.h>
#include "hphp/compiler/statement/function_statement.h"
#include <compiler/statement/function_statement.h>
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/expression/closure_expression.h"
#include <compiler/expression/simple_function_call.h>
#include <compiler/expression/simple_variable.h>
#include <compiler/expression/closure_expression.h>
#include <iomanip>
using namespace HPHP;
@@ -44,7 +44,7 @@ void Construct::resetScope(BlockScopeRawPtr scope, bool resetOrigScope) {
setBlockScope(scope);
if (resetOrigScope) {
ExpressionPtr expr =
dynamic_pointer_cast<Expression>(shared_from_this());
boost::dynamic_pointer_cast<Expression>(shared_from_this());
if (expr) {
expr->setOriginalScope(scope);
}
@@ -439,7 +439,7 @@ public:
// HACK: dump the closure function as a "child" of the
// closure expression
ClosureExpressionPtr c =
dynamic_pointer_cast<ClosureExpression>(cp);
boost::dynamic_pointer_cast<ClosureExpression>(cp);
if (c) {
c->getClosureFunction()->dump(m_spc, m_ar);
}
@@ -454,8 +454,7 @@ private:
void Construct::dump(int spc, AnalysisResultConstPtr ar) {
ConstructDumper cd(spc, ar);
cd.walk(AstWalkerStateVec(ConstructRawPtr(this)),
ConstructRawPtr(), ConstructRawPtr());
cd.walk(ConstructRawPtr(this), ConstructRawPtr(), ConstructRawPtr());
}
void Construct::dump(int spc, AnalysisResultConstPtr ar, bool functionOnly,
+15 -21
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,13 +14,13 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CONSTRUCT_H_
#define incl_HPHP_CONSTRUCT_H_
#ifndef __CONSTRUCT_H__
#define __CONSTRUCT_H__
#include "hphp/util/json.h"
#include "hphp/compiler/code_generator.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/block_scope.h"
#include <util/json.h>
#include <compiler/code_generator.h>
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/block_scope.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -67,7 +67,7 @@ public:
/**
* Base class of Expression and Statement.
*/
class Construct : public std::enable_shared_from_this<Construct>,
class Construct : public boost::enable_shared_from_this<Construct>,
public JSON::CodeError::ISerializable {
protected:
Construct(BlockScopePtr scope, LocationPtr loc);
@@ -166,10 +166,6 @@ 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 {
@@ -182,8 +178,7 @@ public:
return m_blockScope->getContainingClass();
}
void resetScope(BlockScopeRawPtr scope, bool resetOrigScope=false);
void parseTimeFatal(Compiler::ErrorType error, const char *fmt, ...)
ATTRIBUTE_PRINTF(3,4);
void parseTimeFatal(Compiler::ErrorType error, const char *fmt, ...);
virtual int getLocalEffects() const { return UnknownEffect;}
int getChildrenEffects() const;
int getContainedEffects() const;
@@ -191,15 +186,15 @@ public:
virtual bool kidUnused(int i) const { return false; }
template<typename T>
static std::shared_ptr<T> Clone(std::shared_ptr<T> constr) {
static boost::shared_ptr<T> Clone(boost::shared_ptr<T> constr) {
if (constr) {
return dynamic_pointer_cast<T>(constr->clone());
return boost::dynamic_pointer_cast<T>(constr->clone());
}
return std::shared_ptr<T>();
return boost::shared_ptr<T>();
}
template<typename T>
std::shared_ptr<T> Clone(std::shared_ptr<T> constr, BlockScopePtr scope) {
boost::shared_ptr<T> Clone(boost::shared_ptr<T> constr, BlockScopePtr scope) {
if (constr) {
constr = constr->clone();
constr->resetScope(scope);
@@ -299,7 +294,6 @@ 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:
@@ -320,7 +314,7 @@ public:
int getLocalEffects() const { return m_localEffects; }
virtual void effectsCallback() = 0;
protected:
explicit LocalEffectsContainer(Construct::Effect localEffect) :
LocalEffectsContainer(Construct::Effect localEffect) :
m_localEffects(localEffect) {}
LocalEffectsContainer() :
m_localEffects(0) {}
@@ -339,4 +333,4 @@ protected:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CONSTRUCT_H_
#endif // __CONSTRUCT_H__
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,17 +14,17 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/array_element_expression.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/expression/static_member_expression.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/runtime/base/complex-types.h"
#include "hphp/runtime/base/builtin-functions.h"
#include <compiler/expression/array_element_expression.h>
#include <compiler/expression/simple_variable.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/code_error.h>
#include <compiler/option.h>
#include <compiler/expression/static_member_expression.h>
#include <compiler/analysis/function_scope.h>
#include <util/parser/hphp.tab.hpp>
#include <runtime/base/complex_types.h>
#include <runtime/base/builtin_functions.h>
using namespace HPHP;
@@ -167,6 +167,16 @@ void ArrayElementExpression::analyzeProgram(AnalysisResultPtr ar) {
m_variable->analyzeProgram(ar);
if (m_offset) m_offset->analyzeProgram(ar);
if (ar->getPhase() == AnalysisResult::AnalyzeFinal) {
if (!m_global && (m_context & AccessContext) &&
!(m_context & (LValue|RefValue|DeepReference|
UnsetContext|RefParameter|InvokeArgument))) {
TypePtr type = m_variable->getActualType();
if (!type ||
(!type->is(Type::KindOfString) && !type->is(Type::KindOfArray))) {
FunctionScopePtr scope = getFunctionScope();
if (scope && !needsCSE()) scope->setNeedsRefTemp();
}
}
if (m_global) {
if (getContext() & (LValue|RefValue|DeepReference)) {
setContext(NoLValueWrapper);
@@ -181,6 +191,8 @@ void ArrayElementExpression::analyzeProgram(AnalysisResultPtr ar) {
shared_from_this());
}
}
FunctionScopePtr scope = getFunctionScope();
if (scope) scope->setNeedsCheckMem();
} else {
TypePtr at(m_variable->getActualType());
TypePtr et(m_variable->getExpectedType());
@@ -217,10 +229,10 @@ int ArrayElementExpression::getKidCount() const {
void ArrayElementExpression::setNthKid(int n, ConstructPtr cp) {
switch (n) {
case 0:
m_variable = dynamic_pointer_cast<Expression>(cp);
m_variable = boost::dynamic_pointer_cast<Expression>(cp);
break;
case 1:
m_offset = dynamic_pointer_cast<Expression>(cp);
m_offset = boost::dynamic_pointer_cast<Expression>(cp);
break;
default:
assert(false);
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ARRAY_ELEMENT_EXPRESSION_H_
#define incl_HPHP_ARRAY_ELEMENT_EXPRESSION_H_
#ifndef __ARRAY_ELEMENT_EXPRESSION_H__
#define __ARRAY_ELEMENT_EXPRESSION_H__
#include "hphp/compiler/expression/expression.h"
#include <compiler/expression/expression.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -70,4 +70,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ARRAY_ELEMENT_EXPRESSION_H_
#endif // __ARRAY_ELEMENT_EXPRESSION_H__
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#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/parser/hphp.tab.hpp"
#include <compiler/expression/array_pair_expression.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/unary_op_expression.h>
#include <util/parser/hphp.tab.hpp>
using namespace HPHP;
@@ -94,10 +94,10 @@ int ArrayPairExpression::getKidCount() const {
void ArrayPairExpression::setNthKid(int n, ConstructPtr cp) {
switch (n) {
case 0:
m_name = dynamic_pointer_cast<Expression>(cp);
m_name = boost::dynamic_pointer_cast<Expression>(cp);
break;
case 1:
m_value = dynamic_pointer_cast<Expression>(cp);
m_value = boost::dynamic_pointer_cast<Expression>(cp);
break;
default:
assert(false);
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ARRAY_PAIR_EXPRESSION_H_
#define incl_HPHP_ARRAY_PAIR_EXPRESSION_H_
#ifndef __ARRAY_PAIR_EXPRESSION_H__
#define __ARRAY_PAIR_EXPRESSION_H__
#include "hphp/compiler/expression/expression.h"
#include <compiler/expression/expression.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -53,4 +53,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ARRAY_PAIR_EXPRESSION_H_
#endif // __ARRAY_PAIR_EXPRESSION_H__
+29 -35
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,26 +14,26 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/assignment_expression.h"
#include "hphp/compiler/expression/array_element_expression.h"
#include "hphp/compiler/expression/object_property_expression.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/analysis/block_scope.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/runtime/base/complex-types.h"
#include "hphp/runtime/base/builtin-functions.h"
#include <compiler/expression/assignment_expression.h>
#include <compiler/expression/array_element_expression.h>
#include <compiler/expression/object_property_expression.h>
#include <compiler/analysis/code_error.h>
#include <compiler/expression/constant_expression.h>
#include <compiler/expression/simple_variable.h>
#include <compiler/analysis/block_scope.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/constant_table.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/expression/unary_op_expression.h>
#include <util/parser/hphp.tab.hpp>
#include <compiler/option.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/simple_function_call.h>
#include <runtime/base/complex_types.h>
#include <runtime/base/builtin_functions.h>
using namespace HPHP;
@@ -42,11 +42,9 @@ using namespace HPHP;
AssignmentExpression::AssignmentExpression
(EXPRESSION_CONSTRUCTOR_PARAMETERS,
ExpressionPtr variable, ExpressionPtr value, bool ref,
bool rhsFirst /* = false */)
ExpressionPtr variable, ExpressionPtr value, bool ref)
: Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(AssignmentExpression)),
m_variable(variable), m_value(value), m_ref(ref), m_rhsFirst(rhsFirst) {
assert(!m_ref || !m_rhsFirst);
m_variable(variable), m_value(value), m_ref(ref) {
m_variable->setContext(Expression::DeepAssignmentLHS);
m_variable->setContext(Expression::AssignmentLHS);
m_variable->setContext(Expression::LValue);
@@ -92,10 +90,6 @@ void AssignmentExpression::onParseRecur(AnalysisResultConstPtr ar,
// ...as in ClassConstant statement
// We are handling this one here, not in ClassConstant, purely because
// we need "value" to store in constant table.
if (type->is(Type::KindOfArray)) {
parseTimeFatal(Compiler::NoError,
"Arrays are not allowed in class constants");
}
ConstantExpressionPtr exp =
dynamic_pointer_cast<ConstantExpression>(m_variable);
scope->getConstants()->add(exp->getName(), type, m_value, ar, m_variable);
@@ -141,7 +135,7 @@ void AssignmentExpression::analyzeProgram(AnalysisResultPtr ar) {
}
ConstructPtr AssignmentExpression::getNthKid(int n) const {
switch (m_rhsFirst ? 1 - n : n) {
switch (n) {
case 0:
return m_variable;
case 1:
@@ -158,12 +152,12 @@ int AssignmentExpression::getKidCount() const {
}
void AssignmentExpression::setNthKid(int n, ConstructPtr cp) {
switch (m_rhsFirst ? 1 - n : n) {
switch (n) {
case 0:
m_variable = dynamic_pointer_cast<Expression>(cp);
m_variable = boost::dynamic_pointer_cast<Expression>(cp);
break;
case 1:
m_value = dynamic_pointer_cast<Expression>(cp);
m_value = boost::dynamic_pointer_cast<Expression>(cp);
break;
default:
assert(false);
@@ -180,11 +174,11 @@ bool AssignmentExpression::isSimpleGlobalAssign(StringData **name,
Variant v;
if (!m_value->getScalarValue(v) || v.is(KindOfArray)) return false;
if (name) {
*name = makeStaticString(ae->getGlobalName());
*name = StringData::GetStaticString(ae->getGlobalName());
}
if (tv) {
if (v.isString()) {
v = makeStaticString(v.toCStrRef().get());
v = StringData::GetStaticString(v.toCStrRef().get());
}
*tv = *v.asTypedValue();
}
+6 -10
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ASSIGNMENT_EXPRESSION_H_
#define incl_HPHP_ASSIGNMENT_EXPRESSION_H_
#ifndef __ASSIGNMENT_EXPRESSION_H__
#define __ASSIGNMENT_EXPRESSION_H__
#include "hphp/compiler/expression/expression.h"
#include <compiler/expression/expression.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -29,7 +29,7 @@ class AssignmentExpression : public Expression, public IParseHandler {
public:
AssignmentExpression(EXPRESSION_CONSTRUCTOR_PARAMETERS,
ExpressionPtr variable, ExpressionPtr value,
bool ref, bool rhsFirst = false);
bool ref);
DECLARE_EXPRESSION_VIRTUAL_FUNCTIONS;
ExpressionPtr preOptimize(AnalysisResultConstPtr ar);
@@ -45,11 +45,8 @@ public:
}
ExpressionPtr getVariable() { return m_variable;}
ExpressionPtr getStoreVariable() const { return m_variable; }
ExpressionPtr getValue() { return m_value;}
void setVariable(ExpressionPtr v) { m_variable = v; }
void setValue(ExpressionPtr v) { m_value = v; }
bool isRhsFirst() { return m_rhsFirst; }
int getLocalEffects() const;
// $GLOBALS[<literal-string>] = <scalar>;
@@ -60,10 +57,9 @@ private:
ExpressionPtr m_variable;
ExpressionPtr m_value;
bool m_ref;
bool m_rhsFirst;
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ASSIGNMENT_EXPRESSION_H_
#endif // __ASSIGNMENT_EXPRESSION_H__
@@ -1,92 +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. |
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/await_expression.h"
#include "hphp/compiler/analysis/function_scope.h"
using namespace HPHP;
///////////////////////////////////////////////////////////////////////////////
// constructors/destructors
AwaitExpression::AwaitExpression(EXPRESSION_CONSTRUCTOR_PARAMETERS,
ExpressionPtr exp)
: Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(AwaitExpression)),
m_exp(exp), m_label(this) {
}
ExpressionPtr AwaitExpression::clone() {
AwaitExpressionPtr exp(new AwaitExpression(*this));
Expression::deepCopy(exp);
exp->m_exp = Clone(m_exp);
exp->m_label.setExpression(exp.get());
return exp;
}
///////////////////////////////////////////////////////////////////////////////
// parser functions
///////////////////////////////////////////////////////////////////////////////
// static analysis functions
void AwaitExpression::analyzeProgram(AnalysisResultPtr ar) {
assert(getFunctionScope() && getFunctionScope()->isAsync());
m_exp->analyzeProgram(ar);
m_label.setNew();
}
ConstructPtr AwaitExpression::getNthKid(int n) const {
switch (n) {
case 0:
return m_exp;
default:
assert(false);
break;
}
return ConstructPtr();
}
int AwaitExpression::getKidCount() const {
return 1;
}
void AwaitExpression::setNthKid(int n, ConstructPtr cp) {
switch (n) {
case 0:
m_exp = dynamic_pointer_cast<Expression>(cp);
break;
default:
assert(false);
break;
}
}
TypePtr AwaitExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
bool coerce) {
m_exp->inferAndCheck(ar, Type::Some, false);
return Type::Variant;
}
///////////////////////////////////////////////////////////////////////////////
// code generation functions
void AwaitExpression::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) {
cg_printf("await ");
m_exp->outputPHP(cg, ar);
}
-46
Ver Arquivo
@@ -1,46 +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. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_AWAIT_EXPRESSION_H_
#define incl_HPHP_AWAIT_EXPRESSION_H_
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/expression/generation_label.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
DECLARE_BOOST_TYPES(AwaitExpression);
class AwaitExpression : public Expression {
public:
AwaitExpression(EXPRESSION_CONSTRUCTOR_PARAMETERS,
ExpressionPtr exp);
DECLARE_EXPRESSION_VIRTUAL_FUNCTIONS;
ExpressionPtr getExpression() { return m_exp; }
GenerationLabel& label() { return m_label; }
private:
ExpressionPtr m_exp;
GenerationLabel m_label;
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_AWAIT_EXPRESSION_H_
+60 -121
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,24 +14,23 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/binary_op_expression.h"
#include "hphp/compiler/expression/array_element_expression.h"
#include "hphp/compiler/expression/object_property_expression.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/runtime/base/complex-types.h"
#include "hphp/runtime/base/type-conversions.h"
#include "hphp/runtime/base/builtin-functions.h"
#include "hphp/runtime/base/comparisons.h"
#include "hphp/runtime/base/zend-string.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/encaps_list_expression.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/statement/loop_statement.h"
#include "hphp/runtime/base/tv-arith.h"
#include <compiler/expression/binary_op_expression.h>
#include <compiler/expression/array_element_expression.h>
#include <compiler/expression/object_property_expression.h>
#include <compiler/expression/unary_op_expression.h>
#include <util/parser/hphp.tab.hpp>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/constant_expression.h>
#include <runtime/base/complex_types.h>
#include <runtime/base/type_conversions.h>
#include <runtime/base/builtin_functions.h>
#include <runtime/base/comparisons.h>
#include <runtime/base/zend/zend_string.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/encaps_list_expression.h>
#include <compiler/expression/simple_function_call.h>
#include <compiler/expression/simple_variable.h>
#include <compiler/statement/loop_statement.h>
using namespace HPHP;
@@ -72,10 +71,6 @@ BinaryOpExpression::BinaryOpExpression
cType = Collection::MapType;
} else if (strcasecmp(s.c_str(), "stablemap") == 0) {
cType = Collection::StableMapType;
} else if (strcasecmp(s.c_str(), "set") == 0) {
cType = Collection::SetType;
} else if (strcasecmp(s.c_str(), "pair") == 0) {
cType = Collection::PairType;
}
ExpressionListPtr el = static_pointer_cast<ExpressionList>(m_exp2);
el->setCollectionType(cType);
@@ -179,6 +174,9 @@ ExpressionPtr BinaryOpExpression::unneededHelper() {
return static_pointer_cast<Expression>(shared_from_this());
}
///////////////////////////////////////////////////////////////////////////////
// parser functions
///////////////////////////////////////////////////////////////////////////////
// static analysis functions
@@ -191,7 +189,7 @@ int BinaryOpExpression::getLocalEffects() const {
case T_DIV_EQUAL:
case T_MOD_EQUAL: {
Variant v2;
if (!m_exp2->getScalarValue(v2) || equal(v2, 0)) {
if (!m_exp2->getScalarValue(v2) || v2.equal(0)) {
effect = CanThrow;
m_canThrow = true;
}
@@ -218,7 +216,7 @@ ExpressionPtr BinaryOpExpression::simplifyLogical(AnalysisResultConstPtr ar) {
try {
ExpressionPtr rep = foldConst(ar);
if (rep) return replaceValue(rep);
} catch (const Exception& e) {
} catch (Exception e) {
}
return ExpressionPtr();
}
@@ -243,10 +241,10 @@ int BinaryOpExpression::getKidCount() const {
void BinaryOpExpression::setNthKid(int n, ConstructPtr cp) {
switch (n) {
case 0:
m_exp1 = dynamic_pointer_cast<Expression>(cp);
m_exp1 = boost::dynamic_pointer_cast<Expression>(cp);
break;
case 1:
m_exp2 = dynamic_pointer_cast<Expression>(cp);
m_exp2 = boost::dynamic_pointer_cast<Expression>(cp);
break;
default:
assert(false);
@@ -410,7 +408,7 @@ static ExpressionPtr makeIsNull(AnalysisResultConstPtr ar,
SimpleFunctionCallPtr call
(new SimpleFunctionCall(exp->getScope(), loc,
"is_null", false, expList, ExpressionPtr()));
"is_null", expList, ExpressionPtr()));
call->setValid();
call->setActualType(Type::Boolean);
@@ -426,21 +424,13 @@ static ExpressionPtr makeIsNull(AnalysisResultConstPtr ar,
return result;
}
// foldConst() is callable from the parse phase as well as the analysis phase.
// We take advantage of this during the parse phase to reduce very simple
// expressions down to a single scalar and keep the parse tree smaller,
// especially in cases of long chains of binary operators. However, we limit
// the effectivness of this during parse to ensure that we eliminate only
// very simple scalars that don't require analysis in later phases. For now,
// that's just simply scalar values.
ExpressionPtr BinaryOpExpression::foldConst(AnalysisResultConstPtr ar) {
ExpressionPtr optExp;
Variant v1;
Variant v2;
if (!m_exp2->getScalarValue(v2)) {
if ((ar->getPhase() != AnalysisResult::ParseAllFiles) &&
m_exp1->isScalar() && m_exp1->getScalarValue(v1)) {
if (m_exp1->isScalar() && m_exp1->getScalarValue(v1)) {
switch (m_op) {
case T_IS_IDENTICAL:
case T_IS_NOT_IDENTICAL:
@@ -498,23 +488,16 @@ ExpressionPtr BinaryOpExpression::foldConst(AnalysisResultConstPtr ar) {
if (m_exp1->isScalar()) {
if (!m_exp1->getScalarValue(v1)) return ExpressionPtr();
try {
ScalarExpressionPtr scalar1 =
dynamic_pointer_cast<ScalarExpression>(m_exp1);
ScalarExpressionPtr scalar2 =
dynamic_pointer_cast<ScalarExpression>(m_exp2);
// Some data, like the values of __CLASS__ and friends, are not available
// while we're still in the initial parse phase.
if (ar->getPhase() == AnalysisResult::ParseAllFiles) {
if ((scalar1 && scalar1->needsTranslation()) ||
(scalar2 && scalar2->needsTranslation())) {
return ExpressionPtr();
}
}
if (!Option::WholeProgram || !Option::ParseTimeOpts) {
if (Option::OutputHHBC &&
(!Option::WholeProgram || !Option::ParseTimeOpts)) {
// In the VM, don't optimize __CLASS__ if within a trait, since
// __CLASS__ is not resolved yet.
ClassScopeRawPtr clsScope = getOriginalClass();
if (clsScope && clsScope->isTrait()) {
ScalarExpressionPtr scalar1 =
dynamic_pointer_cast<ScalarExpression>(m_exp1);
ScalarExpressionPtr scalar2 =
dynamic_pointer_cast<ScalarExpression>(m_exp2);
if ((scalar1 && scalar1->getType() == T_CLASS_C) ||
(scalar2 && scalar2->getType() == T_CLASS_C)) {
return ExpressionPtr();
@@ -524,112 +507,68 @@ ExpressionPtr BinaryOpExpression::foldConst(AnalysisResultConstPtr ar) {
Variant result;
switch (m_op) {
case T_LOGICAL_XOR:
result = static_cast<bool>(v1.toBoolean() ^ v2.toBoolean());
break;
result = logical_xor(v1, v2); break;
case '|':
*result.asCell() = cellBitOr(*v1.asCell(), *v2.asCell());
break;
result = bitwise_or(v1, v2); break;
case '&':
*result.asCell() = cellBitAnd(*v1.asCell(), *v2.asCell());
break;
result = bitwise_and(v1, v2); break;
case '^':
*result.asCell() = cellBitXor(*v1.asCell(), *v2.asCell());
break;
result = bitwise_xor(v1, v2); break;
case '.':
result = concat(v1.toString(), v2.toString());
break;
result = concat(v1, v2); break;
case T_IS_IDENTICAL:
result = same(v1, v2);
break;
result = same(v1, v2); break;
case T_IS_NOT_IDENTICAL:
result = !same(v1, v2);
break;
result = !same(v1, v2); break;
case T_IS_EQUAL:
result = equal(v1, v2);
break;
result = equal(v1, v2); break;
case T_IS_NOT_EQUAL:
result = !equal(v1, v2);
break;
result = !equal(v1, v2); break;
case '<':
result = less(v1, v2);
break;
result = less(v1, v2); break;
case T_IS_SMALLER_OR_EQUAL:
result = cellLessOrEqual(*v1.asCell(), *v2.asCell());
break;
result = less_or_equal(v1, v2); break;
case '>':
result = more(v1, v2);
break;
result = more(v1, v2); break;
case T_IS_GREATER_OR_EQUAL:
result = cellGreaterOrEqual(*v1.asCell(), *v2.asCell());
break;
result = more_or_equal(v1, v2); break;
case '+':
*result.asCell() = cellAdd(*v1.asCell(), *v2.asCell());
break;
result = plus(v1, v2); break;
case '-':
*result.asCell() = cellSub(*v1.asCell(), *v2.asCell());
break;
result = minus(v1, v2); break;
case '*':
*result.asCell() = cellMul(*v1.asCell(), *v2.asCell());
break;
result = multiply(v1, v2); break;
case '/':
if ((v2.isIntVal() && v2.toInt64() == 0) || v2.toDouble() == 0.0) {
return ExpressionPtr();
}
*result.asCell() = cellDiv(*v1.asCell(), *v2.asCell());
break;
result = divide(v1, v2); break;
case '%':
if ((v2.isIntVal() && v2.toInt64() == 0) || v2.toDouble() == 0.0) {
return ExpressionPtr();
}
*result.asCell() = cellMod(*v1.asCell(), *v2.asCell());
break;
result = modulo(v1, v2); break;
case T_SL:
result = v1.toInt64() << v2.toInt64();
break;
result = shift_left(v1, v2); break;
case T_SR:
result = v1.toInt64() >> v2.toInt64();
break;
result = shift_right(v1, v2); break;
case T_BOOLEAN_OR:
result = v1.toBoolean() || v2.toBoolean(); break;
result = v1 || v2; break;
case T_BOOLEAN_AND:
result = v1.toBoolean() && v2.toBoolean(); break;
result = v1 && v2; break;
case T_LOGICAL_OR:
result = v1.toBoolean() || v2.toBoolean(); break;
result = v1 || v2; break;
case T_LOGICAL_AND:
result = v1.toBoolean() && v2.toBoolean(); break;
case T_INSTANCEOF: {
if (v2.isString()) {
if (v1.isArray() &&
interface_supports_array(v2.getStringData())) {
result = true;
break;
}
if (v1.isString() &&
interface_supports_string(v2.getStringData())) {
result = true;
break;
}
if (v1.isInteger() &&
interface_supports_int(v2.getStringData())) {
result = true;
break;
}
if (v1.isDouble() &&
interface_supports_double(v2.getStringData())) {
result = true;
break;
}
}
result = false;
break;
}
result = v1 && v2; break;
case T_INSTANCEOF:
result = false; break;
default:
return ExpressionPtr();
}
return makeScalarExpression(ar, result);
} catch (...) {
}
} else if (ar->getPhase() != AnalysisResult::ParseAllFiles) {
} else {
switch (m_op) {
case T_LOGICAL_AND:
case T_BOOLEAN_AND:
+5 -6
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_BINARY_OP_EXPRESSION_H_
#define incl_HPHP_BINARY_OP_EXPRESSION_H_
#ifndef __BINARY_OP_EXPRESSION_H__
#define __BINARY_OP_EXPRESSION_H__
#include "hphp/compiler/expression/expression_list.h"
#include <compiler/expression/expression_list.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -41,7 +41,6 @@ public:
virtual bool isRefable(bool checkError = false) const;
bool isShortCircuitOperator() const;
bool isLogicalOrOperator() const;
ExpressionPtr getStoreVariable() const { return m_exp1;}
ExpressionPtr getExp1() { return m_exp1;}
ExpressionPtr getExp2() { return m_exp2;}
int getOp() const { return m_op;}
@@ -71,4 +70,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_BINARY_OP_EXPRESSION_H_
#endif // __BINARY_OP_EXPRESSION_H__
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,17 +14,17 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/class_constant_expression.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/util/hash.h"
#include "hphp/util/util.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/constant_expression.h"
#include <compiler/expression/class_constant_expression.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/file_scope.h>
#include <compiler/analysis/constant_table.h>
#include <compiler/analysis/code_error.h>
#include <util/hash.h>
#include <util/util.h>
#include <compiler/option.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/constant_expression.h>
using namespace HPHP;
@@ -108,7 +108,7 @@ int ClassConstantExpression::getKidCount() const {
void ClassConstantExpression::setNthKid(int n, ConstructPtr cp) {
switch (n) {
case 0:
m_class = dynamic_pointer_cast<Expression>(cp);
m_class = boost::dynamic_pointer_cast<Expression>(cp);
break;
default:
assert(false);
@@ -144,21 +144,11 @@ ExpressionPtr ClassConstantExpression::preOptimize(AnalysisResultConstPtr ar) {
ExpressionPtr value = dynamic_pointer_cast<Expression>(decl);
BlockScope::s_constMutex.unlock();
if (!value->isScalar() &&
(value->is(KindOfClassConstantExpression) ||
value->is(KindOfConstantExpression))) {
std::set<ExpressionPtr> seen;
do {
if (!seen.insert(value).second) return ExpressionPtr();
value = value->preOptimize(ar);
if (!value) return ExpressionPtr();
} while (!value->isScalar() &&
(value->is(KindOfClassConstantExpression) ||
value->is(KindOfConstantExpression)));
}
ExpressionPtr rep = Clone(value, getScope());
bool annotate = Option::FlAnnotate;
Option::FlAnnotate = false; // avoid nested comments on getText
rep->setComment(getText());
Option::FlAnnotate = annotate;
rep->setLocation(getLocation());
return replaceValue(rep);
}
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CLASS_CONSTANT_EXPRESSION_H_
#define incl_HPHP_CLASS_CONSTANT_EXPRESSION_H_
#ifndef __CLASS_CONSTANT_EXPRESSION_H__
#define __CLASS_CONSTANT_EXPRESSION_H__
#include "hphp/compiler/expression/static_class_name.h"
#include "hphp/compiler/analysis/block_scope.h"
#include <compiler/expression/static_class_name.h>
#include <compiler/analysis/block_scope.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -55,4 +55,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CLASS_CONSTANT_EXPRESSION_H_
#endif // __CLASS_CONSTANT_EXPRESSION_H__
+11 -32
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,15 +14,15 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/closure_expression.h"
#include "hphp/compiler/expression/parameter_expression.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/statement/function_statement.h"
#include "hphp/compiler/statement/static_statement.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/file_scope.h"
#include <compiler/expression/closure_expression.h>
#include <compiler/expression/parameter_expression.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/simple_variable.h>
#include <compiler/statement/function_statement.h>
#include <compiler/statement/static_statement.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/file_scope.h>
using namespace HPHP;
@@ -43,20 +43,6 @@ ClosureExpression::ClosureExpression
(new ExpressionList(vars->getScope(), vars->getLocation()));
// push the vars in reverse order, not retaining duplicates
std::set<string> seenBefore;
// Because PHP is insane you can have a use variable with the same
// name as a param name.
// In that case, params win (which is different than zend but much easier)
ExpressionListPtr bodyParams = m_func->getParams();
if (bodyParams) {
int nParams = bodyParams->getCount();
for (int i = 0; i < nParams; i++) {
ParameterExpressionPtr par(
static_pointer_cast<ParameterExpression>((*bodyParams)[i]));
seenBefore.insert(par->getName());
}
}
for (int i = vars->getCount() - 1; i >= 0; i--) {
ParameterExpressionPtr param(
dynamic_pointer_cast<ParameterExpression>((*vars)[i]));
@@ -119,7 +105,7 @@ int ClosureExpression::getKidCount() const {
void ClosureExpression::setNthKid(int n, ConstructPtr cp) {
switch (n) {
case 0:
m_values = dynamic_pointer_cast<ExpressionList>(cp);
m_values = boost::dynamic_pointer_cast<ExpressionList>(cp);
break;
default:
assert(false);
@@ -181,13 +167,6 @@ void ClosureExpression::analyzeProgram(AnalysisResultPtr ar) {
}
}
}
FunctionScopeRawPtr container =
getFunctionScope()->getContainingNonClosureFunction();
if (container && container->isStatic()) {
m_func->getModifiers()->add(T_STATIC);
}
}
TypePtr ClosureExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
+5 -9
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CLOSURE_EXPRESSION_H_
#define incl_HPHP_CLOSURE_EXPRESSION_H_
#ifndef __CLOSURE_EXPRESSION_H__
#define __CLOSURE_EXPRESSION_H__
#include "hphp/compiler/expression/expression.h"
#include <compiler/expression/expression.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -40,16 +40,12 @@ public:
FunctionStatementPtr getClosureFunction() { return m_func; }
ExpressionListPtr getClosureVariables() { return m_vars; }
ExpressionListPtr getClosureValues() { return m_values; }
StringData* getClosureClassName() { return m_closureClassName; }
void setClosureClassName(StringData* value) { m_closureClassName = value; }
bool hasStaticLocals();
private:
FunctionStatementPtr m_func;
ExpressionListPtr m_vars;
ExpressionListPtr m_values;
StringData* m_closureClassName;
static TypePtr s_ClosureType;
@@ -58,4 +54,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CLOSURE_EXPRESSION_H_
#endif // __CLOSURE_EXPRESSION_H__
+28 -22
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,21 +14,21 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/compiler/analysis/block_scope.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/util/hash.h"
#include "hphp/util/util.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/runtime/ext/ext_misc.h"
#include <compiler/analysis/file_scope.h>
#include <compiler/expression/constant_expression.h>
#include <compiler/analysis/block_scope.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/constant_table.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/code_error.h>
#include <util/hash.h>
#include <util/util.h>
#include <compiler/option.h>
#include <compiler/parser/parser.h>
#include <util/parser/hphp.tab.hpp>
#include <compiler/expression/scalar_expression.h>
#include <runtime/ext/ext_misc.h>
using namespace HPHP;
@@ -37,11 +37,10 @@ using namespace HPHP;
ConstantExpression::ConstantExpression
(EXPRESSION_CONSTRUCTOR_PARAMETERS,
const string &name, bool hadBackslash, const string &docComment)
const string &name, const string &docComment)
: Expression(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(ConstantExpression)),
m_name(name), m_origName(name), m_hadBackslash(hadBackslash),
m_docComment(docComment), m_valid(false), m_dynamic(false),
m_visited(false), m_depsSet(false) {
m_name(name), m_docComment(docComment),
m_valid(false), m_dynamic(false), m_visited(false), m_depsSet(false) {
}
void ConstantExpression::onParse(AnalysisResultConstPtr ar,
@@ -117,9 +116,11 @@ bool ConstantExpression::canonCompare(ExpressionPtr e) const {
// static analysis functions
Symbol *ConstantExpression::resolveNS(AnalysisResultConstPtr ar) {
bool ns = m_name[0] == '\\';
if (ns) m_name = m_name.substr(1);
BlockScopeConstPtr block = ar->findConstantDeclarer(m_name);
if (!block) {
if (!hadBackslash() && Option::WholeProgram) {
if (ns) {
int pos = m_name.rfind('\\');
m_name = m_name.substr(pos + 1);
block = ar->findConstantDeclarer(m_name);
@@ -150,6 +151,8 @@ void ConstantExpression::analyzeProgram(AnalysisResultPtr ar) {
}
} else if (ar->getPhase() == AnalysisResult::AnalyzeFinal && m_dynamic) {
getFileScope()->addConstantDependency(ar, m_name);
FunctionScopePtr scope = getFunctionScope();
if (scope) scope->setNeedsCheckMem();
}
}
@@ -194,7 +197,10 @@ ExpressionPtr ConstantExpression::preOptimize(AnalysisResultConstPtr ar) {
}
}
ExpressionPtr rep = Clone(value, getScope());
bool annotate = Option::FlAnnotate;
Option::FlAnnotate = false; // avoid nested comments on getText
rep->setComment(getText());
Option::FlAnnotate = annotate;
rep->setLocation(getLocation());
return replaceValue(rep);
}
@@ -277,5 +283,5 @@ TypePtr ConstantExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
// code generation functions
void ConstantExpression::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) {
cg_printf("%s", getNonNSOriginalName().c_str());
cg_printf("%s", m_name.c_str());
}
+5 -17
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_CONSTANT_EXPRESSION_H_
#define incl_HPHP_CONSTANT_EXPRESSION_H_
#ifndef __CONSTANT_EXPRESSION_H__
#define __CONSTANT_EXPRESSION_H__
#include "hphp/compiler/expression/expression.h"
#include <compiler/expression/expression.h>
#define CONSTANT(value) makeConstant(ar, value)
@@ -30,7 +30,6 @@ class ConstantExpression : public Expression, IParseHandler {
public:
ConstantExpression(EXPRESSION_CONSTRUCTOR_PARAMETERS,
const std::string &name,
bool hadBackslash,
const std::string &docComment = "");
DECLARE_BASE_EXPRESSION_VIRTUAL_FUNCTIONS;
@@ -51,14 +50,6 @@ public:
virtual bool canonCompare(ExpressionPtr e) const;
const std::string &getName() const { return m_name;}
const std::string &getOriginalName() const { return m_origName;}
const std::string getNonNSOriginalName() const {
auto nsPos = m_origName.rfind('\\');
if (nsPos == string::npos) {
return m_origName;
}
return m_origName.substr(nsPos + 1);
}
const std::string &getDocComment() const {
return m_docComment;
}
@@ -73,13 +64,10 @@ public:
std::string getComment() { return m_comment;}
bool isValid() const { return m_valid; }
bool isDynamic() const { return m_dynamic; }
bool hadBackslash() const { return m_hadBackslash; }
private:
Symbol *resolveNS(AnalysisResultConstPtr ar);
std::string m_name;
std::string m_origName;
bool m_hadBackslash;
std::string m_docComment;
std::string m_comment; // for inlined constant name
bool m_valid;
@@ -91,4 +79,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_CONSTANT_EXPRESSION_H_
#endif // __CONSTANT_EXPRESSION_H__
+18 -14
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,16 +14,16 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/dynamic_function_call.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/simple_function_call.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/util/util.h"
#include "hphp/compiler/option.h"
#include "hphp/compiler/analysis/variable_table.h"
#include <compiler/expression/dynamic_function_call.h>
#include <compiler/analysis/code_error.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/simple_function_call.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/analysis/class_scope.h>
#include <util/util.h>
#include <compiler/option.h>
#include <compiler/analysis/variable_table.h>
using namespace HPHP;
@@ -34,7 +34,7 @@ DynamicFunctionCall::DynamicFunctionCall
(EXPRESSION_CONSTRUCTOR_PARAMETERS,
ExpressionPtr name, ExpressionListPtr params, ExpressionPtr cls)
: FunctionCall(EXPRESSION_CONSTRUCTOR_PARAMETER_VALUES(DynamicFunctionCall),
name, "", false, params, cls) {
name, "", params, cls) {
}
ExpressionPtr DynamicFunctionCall::clone() {
@@ -84,7 +84,7 @@ ExpressionPtr DynamicFunctionCall::preOptimize(AnalysisResultConstPtr ar) {
}
return ExpressionPtr(NewSimpleFunctionCall(
getScope(), getLocation(),
name, false, m_params, cls));
name, m_params, cls));
}
}
return ExpressionPtr();
@@ -103,7 +103,11 @@ TypePtr DynamicFunctionCall::inferTypes(AnalysisResultPtr ar, TypePtr type,
}
}
m_nameExp->inferAndCheck(ar, Type::Some, false);
if (!m_class && m_className.empty()) {
m_nameExp->inferAndCheck(ar, Type::Variant, false);
} else {
m_nameExp->inferAndCheck(ar, Type::String, false);
}
if (m_params) {
for (int i = 0; i < m_params->getCount(); i++) {
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_DYNAMIC_FUNCTION_CALL_H_
#define incl_HPHP_DYNAMIC_FUNCTION_CALL_H_
#ifndef __DYNAMIC_FUNCTION_CALL_H__
#define __DYNAMIC_FUNCTION_CALL_H__
#include "hphp/compiler/expression/function_call.h"
#include <compiler/expression/function_call.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -37,4 +37,4 @@ public:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_DYNAMIC_FUNCTION_CALL_H_
#endif // __DYNAMIC_FUNCTION_CALL_H__
+7 -7
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/dynamic_variable.h"
#include "hphp/compiler/analysis/block_scope.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/analysis/file_scope.h"
#include <compiler/expression/dynamic_variable.h>
#include <compiler/analysis/block_scope.h>
#include <compiler/analysis/code_error.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/analysis/file_scope.h>
using namespace HPHP;
@@ -66,7 +66,7 @@ int DynamicVariable::getKidCount() const {
void DynamicVariable::setNthKid(int n, ConstructPtr cp) {
switch (n) {
case 0:
m_exp = dynamic_pointer_cast<Expression>(cp);
m_exp = boost::dynamic_pointer_cast<Expression>(cp);
break;
default:
assert(false);
+5 -5
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,10 +14,10 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_DYNAMIC_VARIABLE_H_
#define incl_HPHP_DYNAMIC_VARIABLE_H_
#ifndef __DYNAMIC_VARIABLE_H__
#define __DYNAMIC_VARIABLE_H__
#include "hphp/compiler/expression/expression.h"
#include <compiler/expression/expression.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -40,4 +40,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_DYNAMIC_VARIABLE_H_
#endif // __DYNAMIC_VARIABLE_H__
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/encaps_list_expression.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/binary_op_expression.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/runtime/base/builtin-functions.h"
#include <compiler/expression/encaps_list_expression.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/binary_op_expression.h>
#include <compiler/analysis/code_error.h>
#include <runtime/base/builtin_functions.h>
using namespace HPHP;
@@ -70,7 +70,7 @@ int EncapsListExpression::getKidCount() const {
void EncapsListExpression::setNthKid(int n, ConstructPtr cp) {
switch (n) {
case 0:
m_exps = dynamic_pointer_cast<ExpressionList>(cp);
m_exps = boost::dynamic_pointer_cast<ExpressionList>(cp);
break;
default:
assert(false);
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,11 +14,11 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ENCAPS_LIST_EXPRESSION_H_
#define incl_HPHP_ENCAPS_LIST_EXPRESSION_H_
#ifndef __ENCAPS_LIST_EXPRESSION_H__
#define __ENCAPS_LIST_EXPRESSION_H__
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/analysis/analysis_result.h"
#include <compiler/expression/expression.h>
#include <compiler/analysis/analysis_result.h>
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
@@ -46,4 +46,4 @@ private:
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ENCAPS_LIST_EXPRESSION_H_
#endif // __ENCAPS_LIST_EXPRESSION_H__
+84 -38
Ver Arquivo
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 2010- 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 |
@@ -14,29 +14,28 @@
+----------------------------------------------------------------------+
*/
#include "hphp/compiler/expression/expression.h"
#include "hphp/compiler/analysis/code_error.h"
#include "hphp/compiler/parser/parser.h"
#include "hphp/parser/hphp.tab.hpp"
#include "hphp/util/util.h"
#include "hphp/compiler/analysis/class_scope.h"
#include "hphp/compiler/analysis/function_scope.h"
#include "hphp/compiler/expression/scalar_expression.h"
#include "hphp/compiler/expression/constant_expression.h"
#include "hphp/compiler/expression/expression_list.h"
#include "hphp/compiler/expression/simple_variable.h"
#include "hphp/compiler/expression/assignment_expression.h"
#include "hphp/compiler/expression/array_pair_expression.h"
#include "hphp/compiler/expression/array_element_expression.h"
#include "hphp/compiler/expression/object_property_expression.h"
#include "hphp/compiler/expression/unary_op_expression.h"
#include "hphp/compiler/expression/binary_op_expression.h"
#include "hphp/compiler/analysis/constant_table.h"
#include "hphp/compiler/analysis/variable_table.h"
#include "hphp/compiler/expression/function_call.h"
#include "hphp/compiler/analysis/file_scope.h"
#include "hphp/util/hash.h"
#include "hphp/runtime/base/array-iterator.h"
#include <compiler/expression/expression.h>
#include <compiler/analysis/code_error.h>
#include <compiler/parser/parser.h>
#include <util/parser/hphp.tab.hpp>
#include <util/util.h>
#include <compiler/analysis/class_scope.h>
#include <compiler/analysis/function_scope.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/constant_expression.h>
#include <compiler/expression/expression_list.h>
#include <compiler/expression/simple_variable.h>
#include <compiler/expression/assignment_expression.h>
#include <compiler/expression/array_pair_expression.h>
#include <compiler/expression/array_element_expression.h>
#include <compiler/expression/object_property_expression.h>
#include <compiler/expression/unary_op_expression.h>
#include <compiler/analysis/constant_table.h>
#include <compiler/analysis/variable_table.h>
#include <compiler/expression/function_call.h>
#include <compiler/analysis/file_scope.h>
#include <util/hash.h>
#include <runtime/base/array/array_iterator.h>
using namespace HPHP;
@@ -71,7 +70,6 @@ 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();
}
@@ -146,7 +144,7 @@ bool Expression::hasSubExpr(ExpressionPtr sub) const {
Expression::ExprClass Expression::getExprClass() const {
ExprClass cls = Classes[m_kindOf];
if (cls == Update) {
ExpressionPtr k = getStoreVariable();
ExpressionPtr k = getNthExpr(0);
if (!k || !(k->hasContext(OprLValue))) cls = Expression::None;
}
return cls;
@@ -370,7 +368,7 @@ void Expression::setTypes(AnalysisResultConstPtr ar, TypePtr actualType,
}
if (m_actualType->isSpecificObject()) {
std::const_pointer_cast<AnalysisResult>(ar)->
boost::const_pointer_cast<AnalysisResult>(ar)->
addClassDependency(getFileScope(), m_actualType->getName());
}
}
@@ -508,7 +506,7 @@ ExpressionPtr Expression::MakeConstant(AnalysisResultConstPtr ar,
const std::string &value) {
ConstantExpressionPtr exp(new ConstantExpression(
scope, loc,
value, false));
value));
if (value == "true" || value == "false") {
if (ar->getPhase() >= AnalysisResult::PostOptimize) {
exp->m_actualType = Type::Boolean;
@@ -676,14 +674,6 @@ bool Expression::isArray() const {
return false;
}
bool Expression::isCollection() const {
if (is(KindOfBinaryOpExpression)) {
return
static_cast<const BinaryOpExpression*>(this)->getOp() == T_COLLECTION;
}
return false;
}
bool Expression::isUnquotedScalar() const {
if (!is(KindOfScalarExpression)) return false;
return !((ScalarExpression*)this)->isQuoted();
@@ -697,7 +687,7 @@ ExpressionPtr Expression::MakeScalarExpression(AnalysisResultConstPtr ar,
ExpressionListPtr el(new ExpressionList(scope, loc,
ExpressionList::ListKindParam));
for (ArrayIter iter(value.toArray()); iter; ++iter) {
for (ArrayIter iter(value); iter; ++iter) {
ExpressionPtr k(MakeScalarExpression(ar, scope, loc, iter.first()));
ExpressionPtr v(MakeScalarExpression(ar, scope, loc, iter.second()));
if (!k || !v) return ExpressionPtr();
@@ -711,7 +701,7 @@ ExpressionPtr Expression::MakeScalarExpression(AnalysisResultConstPtr ar,
} else if (value.isNull()) {
return MakeConstant(ar, scope, loc, "null");
} else if (value.isBoolean()) {
return MakeConstant(ar, scope, loc, value.toBoolean() ? "true" : "false");
return MakeConstant(ar, scope, loc, value ? "true" : "false");
} else {
return ScalarExpressionPtr
(new ScalarExpression(scope, loc, value));
@@ -868,3 +858,59 @@ bool Expression::getTypeCastPtrs(
return dstType && srcType && ((m_context & LValue) == 0) &&
Type::IsCastNeeded(ar, srcType, dstType);
}
bool Expression::needsFastCastTemp(AnalysisResultPtr ar) {
if (is(KindOfSimpleVariable)) return false;
if (!canUseFastCast(ar)) return false;
if (hasAnyContext(ExistContext|AccessContext) &&
(is(KindOfObjectPropertyExpression) ||
is(KindOfArrayElementExpression))) {
return false;
}
assert(m_actualType);
return !m_actualType->isPrimitive();
}
bool Expression::couldCppTypeBeReferenced() {
if (is(KindOfDynamicVariable)) return true;
SimpleVariablePtr p(
dynamic_pointer_cast<SimpleVariable>(
shared_from_this()));
BlockScopeRawPtr scope(getScope());
VariableTablePtr vt(scope ? scope->getVariables() : VariableTablePtr());
// a simple variable could have its CPP type referenced if:
// it could be aliased or,
// it is a non-lval parameter or,
// the scope it lives in has a dynamic variable or contains extract()
// note that we default to true (the conservative case) if no symbol
// or variable table is found
return p ?
(p->couldBeAliased() ||
(!p->getSymbol() ||
(p->getSymbol()->isParameter() && !p->getSymbol()->isLvalParam())) ||
(!vt || (vt->getAttribute(VariableTable::ContainsDynamicVariable) ||
vt->getAttribute(VariableTable::ContainsExtract)))) :
!isTemporary();
}
bool Expression::canUseFastCast(AnalysisResultPtr ar) {
TypePtr srcType, dstType;
getTypeCastPtrs(ar, srcType, dstType);
// if the impl type is Variant and the actual type is known
// with a fast cast method, and we have a dst type that
// is not Variant (in CPP), then we have something to benefit
// from doing a fast cast and should emit one.
if (m_implementedType &&
Type::IsMappedToVariant(m_implementedType) &&
m_actualType &&
Type::HasFastCastMethod(m_actualType) &&
dstType &&
!Type::IsMappedToVariant(dstType)) {
if (m_assertedType) return true;
if (is(KindOfSimpleVariable) &&
static_cast<SimpleVariable*>(this)->isGuarded()) {
return true;
}
}
return false;
}

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