I combed through HipHop's grammar and noticed a few bugs. HipHop's grammar does not allow for traits to be declared anywhere except toplevel scope (whereas Zend allows for this), and the grammar allows for bogus singleton XHP tags such as '<foo a="1" /foo>' (which are not allowed by the original XHP grammar given by xhpast). This diff fixes these bugs, and it also removes some superfluous rules, duplicated rules, and dead rules from the grammar. I also took a look at 14 shift/reduce conflicts in the grammar to see if I could eliminate most of them. 4 of the 14 conflicts went away when I fixed the issue with the xhp_tag_body rules and when I removed the dead type_decl rules. Of the 10 remaining conflicts, 2 were due to the if/else rules and the other 8 were due to the "expr -> expr [ dim_offset ]" rule. Conflicts due to "if/else" are well understood and conventional wisdom says we're better off just accepting these conflicts instead of contorting the grammar to try to get rid of them. Conflicts due to "expr -> expr [ dim_offset ]", however, are not really well understood and there are a lot of them, so it seemed worth fixing. "expr -> expr [ dim_offset ]" was originally added to the grammar to support using function calls as the base for array element expressions (ex. "$x = f()"). The rules for variable, calls, array elements, and object properties were written in a very weird way that made them hard to update, so I took the opportunity to rewrite these rules in a more natural form and I updated the rules to support using function calls as the base for array element expressions. Finally, I ran into cases where developers were using array literals, class constants, and parenthesized expressions as the base of array element expressions, so I introduced 'dim_expr' rules so that HipHop's grammar will continue to support these cases.
pcre_exec checks that its subject is valid utf8 every time it's called (unless told not to). Our preg_split implementation can end up calling pcre_exec once for every character in the subject for certain inputs, so rechecking the utf8 validity of the subject is a waste of cycles.
try/catch()/finally and try/finally constuctions added to hphp. Code is translated into C++. There still a lot to do: 1. Throw an exception when there's an unhandled exception in finally scope; 2. Write test units; 3. Support finally in virtual machine; 4. Return an error if there's a yield statement into try/finally scope.
This means we can avoid compiling with ENABLE_INTERCEPTS, which significantly reduces the size of the binary.
Converting to ThreadLocalSingleton means each MemoryManager instance is stored directly in __thread memory instead of malloc, and allows clients to directly access it via the x64 FS register. This avoids needing SmartAllocatorImpl::m_stats to update stats. Moved The GarbageList static_assert to memory_manager.cpp.
Failing to call this when there are live RequestLocal objects will can cause them to access deleted objects during pthread's shutdown (calling OnThreadExit). This fixes and adds assertions about ref counts that makes this easier to hit this in a debug build.
Some flib tests were failing, and the lines I looked at were for SetOpM. The bytecode.cpp version of these two uses MoreWarnings to decide whether warn is true for setHelper, so do something similar for the translator.
This is a wrapper around boost::numeric_cast, to give a helpful error message if we attempt to use an out of range immediate or jump in the assembler. I'm sure there are other places in the codebase it can be useful but this was the first that came to mind. In RELEASE=1 builds it's just a static_cast so there should be no runtime overhead.
The translations for the M* instructions call getMInstrCtx to set MInstrState::ctx if the context is not fixed, or if there are property accesses in the vector. But MInstrState::ctx is only read when the context is not fixed AND there are property accesses in the vector. Also found an issue where the BaseN* helpers would access the current frame without a VMRegAnchor. Fixed by passing in the correct fp as a parameter.
This checks to see whether a file could be included. For hhvm in sandbox mode, this just checks the existence of the file. For hhvm in RepoAuthoritative mode, it ignores the filesystem, and looks to see whether the file is in the repo. For hphpc it checks to see if the file was compiled into the binary.
Vector::pop is advertised as returning the value that was removed from the Vector. Make it so.
apc can contain some large strings
add a memory section to the information returned by ServerStats::ReportStatus() for threads handling requests
Implement generic translation capability for all *M instructions. Generic translations are emitted as series of helper function calls. Add the Eval.JitMGeneric runtime option to allow generic *M instruction translation to be disabled, for regression testing/reversion purposes. Fix callUnaryStubImpl() to account for pushing rdi when argument is rsp+disp. Fix the interpreter to warn for BaseLW* as needed. Fix the interpreter to initialize IncDecL's stack output before operating on it.
Using comparison operators (==, !=, <>, <, <=, >, >=) with arrays and objects can be expensive and produce strange results in some cases. Rather than having collections match this behavior, I think it's better to disallow using these operators to compare a collection with an integer, string. This diff adds checks to either raise a warning or throw an exception (depending on a runtime option) when any of these operators is used to compare collection with an integer, string, array, or object. Note that collections are still allowed to be compared with null, true, and false using the comparison operators. Also, collections can still be compared for reference equality with === and !==.
Update idx() to support collections. Also, for some collections the contains(), remove(), and discard() methods did not throw exceptions if the key type was invalid, fix that.
This reverts commit 4b24643
The current error messages for FPushObjMethod and FPushClsMethod are a bit cryptic. This diff updates these error messages to match Zend.
For the cost of one more pointer in struct FullPos, we can simplify the tracking of an array's currently active mutable iterators. The current array (vector of FullPos*) requires a secondary malloc() if there are >1 iterators. Using a linked list never requires malloc, and keeps the common case fast (most recently added iterator is the first one in the list).
Just added checkArrays() and whether or not we have exactly one pseudo-main.
It was generating a RetC on an UnboxR (on purpose) and a try region that started with a non-empty stack. Also adds support for an HHVM_VERIFY_VERBOSE mode.
… of arGetContextClass. The static property accessor bytecode translations were not checking whether the context is fixed, which is incorrect when translating pseudomains. This diff adds a isContextFixed check to analyze[CGetS, SetS] to make sure we are not in pseudo-main. It also replaces uses of arGetContextClass with curFunc()->cls() where its clear that we don't want to be in pseudomain.
Use SmartAllocator to allocate VectorArray and ZendArray buffers up to 64 entries. The size of inline allocation space (4 slots for VectorArray, 8 Bucket*'s for ZendArray) is unchanged, since experiments showed any change in either direction was a regression. Also use helper functions to round up to powers of 2 rather than a while loop; the helpers use __builtin_clz.