No emitted bytecode relies on Continuation being stored in local 0
anymore. Stop using local 0 for this purpose and compute offset
to the Continuation at JIT time. 16 bytes of memory freed.
At this point all locals of Continuation construction wrapper share the
same indices with their respective locals of Continuation body, which
should allow further optimizations.
This is exactly what Zend's parser does now. I'm a little sad about
adding the bool parameter, but all the checking code was exactly
duplicated otherwise, and that seemed like the worse alternative.
Fixes#854
We'd like to start using ##mixed## instead of ##var## for attribute types to be consistent with Hack. As a followup to this (once released), we would codemod all ##var## to ##mixed##.
The goal of this diff is to clean up the current work-in-progress and check
it in so that others may contribute if they have time.
The program currently outputs the HHVM tree as well as the xhpast-like
json, for ease of debugging. There is a little helper program jsonpretty.py
to make the trees more readable, e.g.
_build/dbg/hphp/util/parser/xhpast/xhpast2 <some php file> | hphp/util/parser/xhpast/xhpast2/jsonpretty.py
XML comment syntax for XHP is one of the top wishlist items within the UIE group (+ some other people).
Currently, the only way to have comments inside XHP blocks is to use expressions and block comments, e.g.
<div>{/* comment */}</div>
After this change, you can use the more familiar syntax. This syntax is limited to XHP child contexts:
// Only single-line, doc, block comments work outside XHP
$xhp =
<div>
<!--XML comments only work within XHP children contexts-->
</div>;
Based on http://www.w3.org/TR/REC-xml/#sec-comments - except we ignore the rule about double hyphens ('--') within a comment because we don't care about SGML.
Updates continuations to allow yielding of a key-value
pair from a generator. Adds bytecode instructions (PackContK,
ContKey) for using the new feature, and adds IR instructions
(ContUpdateIdx, ContIncKey) to help get it down to the metal
(in particular, ContIncKey attempts to keep the current use-cases
as fast as possible).
Replace NameDef with a new struct of runtime-resolved typedef
information. This needs to include more than Class* or Typedef*,
because we might have nullable type aliases, or a non-nullable alias
to a nullable typedef, or vice versa. Switch to the new
TypeAnnotation stuff in TypedefStatement instead of just strings so
support for this isn't weird (shapes are outside of this for now
though---see the hack in parser.cpp). Also fixes support for type
aliases to mixed.
Adds support for checking ?Foo type hints in VerifyParamType.
The parameter must have type Foo or null. Failing to pass the hint is
reported as a warning instead of a recoverable error for now for
migration reasons---we'll want to convert it to be the same as normal
type hints later.
If you have an alias named "Foo", and a class named "Foo" in
the same program, we should not be treating instanceof (and probably
other things) as if the class name is unique.
This is gone as of Zend 5.4: as far as I can tell, anything other than a
positive integer literal is a parse error (including constants, "1 + 1",
etc.) Let's get rid of it. The mere fact that this construct ever
existed in any programming language is deeply horrifying.
This lets us get rid of all the goofy code that subtracts 1 from the top
value on the stack, does IterFree if needed, and jumps to the next
level. Now, we can hardcode the necessary IterFrees and do a single
jump, right where the break/continue actually is.
The error message for using a non-integer expression is less helpful
than Zend's (Zend says "non-constant operand not supported"; ours is
"unexpected T_VARIABLE" or whatever). It wouldn't be that hard to do in
our parser, if we think that's helpful. I don't think it matters,
though.
This reverts commit 2e9677b7c3f37e9627b9cbc9a6ddec82a10e7215.
Third time is the charm. I hid it from reflection, but I missed `get_class_methods`.
The diff betweenn this and what was reverted is https://phabricator.fb.com/P2217891 and then I did https://phabricator.fb.com/P2217904 because it looked like it should be done.
Save 8 bytes of m_args and its initialization for Continuations without
func_get_args() call (does not save real memory due to 16-byte alignment).
Store variable arguments in optional local.
The problem was a few:
* All constant declarations were wrapped in a statement list. The merge-only check was allowing top-level `define()`s but not top level statement lists. I unwrapped them. I have no idea why it was done. Probalby just cargo cult programming.
* When converting a UnitEmitter to a Unit we only allowed constants in RepoAuthoritative mode and not systemlib mode.
* Systemlib constants weren't being set as UnitMergeKindPersistentDefine
* UnitMergeKindPersistentDefine constants weren't being marked mergeOnly when pulling out of a repro
For generic constraints, the grammar (incorrectly) did not allow for
generic types on the right hand side of the "as" keyword. This diff fixes
the grammar appropriately.
runtime/eval is a relic of a bygone era. As long as we're cleaning up
our directory structure, let's move FileRepository (the only remaining
thing in runtime/eval/runtime) to where it makes sense.
runtime/eval still contains the debugger, which would probably make more
sense as runtime/debugger, but I don't want to throw a wrench in the
works for @mikemag and @hermanv unnecessarily.
Closures and generators are really hard to reason about in backtraces.
For generators, I took the exact name of the method and put ##$continuation##. I put it at the end so it reads exactly like a method name since in WWW we use them almost the same as the method itself.
For closures, I named the class ##Closue$Class::method#num## where num is an optional autoincrementing number.
I decided to stop prefixing the methods with ##0## which is breaking the reflection tests.
This basically redoes D782498 and D750608 but it works in repo mode.
Classes need to take up space in the alias map (according to zend).
Suprisingly, functions and constants don't. When importing a duplicate, zend doesn't do anything and just continues, and we currently overwrite the symbol. Should I match zend on this, or is the fact that we both continue working good enough?
A shebang allow a script to be run as an executable on UNIX
systems. PHP allows shebangs, but Hack does not. This
changeset allows Hack to have shebangs like in PHP.
I was learning from @jdelong and he said that you should use
double quotes for local includes and angle brackets for library
includes. I asked why our code was the way it was, and he said he wanted
to clean it up. I beat him to it :)
Conflicts:
hphp/runtime/base/server/admin_request_handler.cpp
hphp/runtime/vm/named_entity.h
This test didn't really intentionally test this, but it caught us not eating comments on namespaces.
I don't understand the difference between ##ParserBase## and ##Parser##. Maybe this belongs here? It needed to be here to have access to ##pushComment##.
I wanted to get closer to zend's implementation but they seem to do scanning and parsing at the same time. We don't have the state of the parser when the scanner sees the ##?>## token. I think this is the next best thing if we don't want the refactor of D808985
It turned out a lot of the namespace stuff still worked. The biggest thing for the first pass is that we don't fallback to the global function or constant if there isn't a namespaced one.
Also, when a constant has a ##\## anywhere in it it throw an error when it isn't defined, instead of assuming the string.
Update a number of things to make optionally generating the parser at
build time possible. @sgolemon will add the OSS pieces of this in a
separate commit.
@override-unit-failures
D774978 was checked in with a broken test. New tests go in test/slow
now. The test was broken because @drussi apparently didn't rebuild the
parser after his last diff update (changing 's' to 't').
This is intended so reflection can be used (via getTypehintText and getReturnTypehintText) to regenerate code the user annotated with types. Essentially using reflection to intrispect code in order to generate type safe
(hack safe) code. That is particularly important for the tools that do dependency injection. The runtime should be oblivious to the change as the rich type annotation is currently only stored for the sake of reflection. For
functions the values are in the shared portion which is cold and should also take care of traits.
As a user, this often annoyed me that I couldn't get any debugging info
out of the name and then @ahupp asked for it.
I didn't really know what to name closure ones as the name is done at
emission time. So I went with ##{closure}##. I'm not sure how I feel
about that since it will be uncorrelated with the emitted name.
While I was in there, I deleted a lot of unused code.
I'm totally open to other names and ideas.
A small change to optimize very simple binary operators in the parser. This avoids building very large parse trees for super-large expressions and folds binary operators involving two scalars directly in the parser. I've limited this to simple scalars since it's easy to prove they don't have anything too interesting going on in the other analysis phases leading up to BinaryOpExpression's normal folding. This works for all binary operators.
This is the first part of the work to expose type constraint and generic all the way to reflection. This first DIFF exposes the return type with generic types coming next.