1,920 karma · joined December 16, 2011
Because the alternative conflicts in case we ever introduce generics. Consider <?php new Foo<Bar?> ?>. This could either be a generic instantiation, or it could be the same as <?php ((new Foo) < Bar) ?> ?> (which is how it is currently interpreted -- this is valid PHP code!)
Of course, you could specify how this is to be interpreted and implement the necessary parser hacks to make it happen, but it's best to avoid the issue altogether by using ? as a prefix.
I assume that this is also the reason why Hack does the same.
On the other hand, there are projects that do successfully use LLVM for JIT. We now experiment with dynasm, which doesn't optimize, but is fast and much more pleasant to use. libjit looks like another popular option. [1]: http://hhvm.com/blog/10205/llvm-code-generation-in-hhvm
Whether or not the JIT will bring a major improvement for applications is not yet clear, but the hope is obviously there.
I think this is all there really is to it. Some customers wanted to have backdated SHA1 certificates so they could continue supporting platforms that do not accept SHA256 certificates. WoSign decided to oblige them.
Does the second issue imply that OpenSSL does not have any automated tests for the CRL functionality?
This is the issue I ran into when investigating use of RH hashing in PHP -- the average case had good performance, but there were pathological cases exhibiting extremely high clustering in a mostly empty table. The reason was the low-quality hash (for integer keys the identity function).
x1 = ...
if (x1 > 0) {
x2 = pi(x1 & RANGE[1..])
use(x2)
} else {
x3 = pi(x1 & RANGE[..0])
use(x3)
}
x4 = phi(x2, x3) // if used
I have placed the pi nodes in the blocks, but semantically they are placed along the control edge.Ref e.g. e-SSA in the ABCD value range inference algorithm.
What does this statement mean and why is it not tautological?
Those are just the three top-level dependencies. The package has 9 recursive dependencies.
There's also a nice table explaining how a package called "is-positive" managed to reach version 3.1.0.
And in this context, macro-expanded, inlined code, exploiting the assumption of no undefined behavior occurring starts making a lot more sense. Sure, if you consider something like
int x = *ptr;
if (ptr != NULL) {
*ptr = 1;
}
you may not unreasonably say that, as there is an explicit ptr != NULL check in there, probably that's what the programmer intended -- so we should not replace ptr != NULL with a constant 0 because that pointer was already dereferenced.However if the real code is
int x = *ptr;
do_something_with_ptr(ptr)
and the do_something_with_ptr() function just happens to contain a NULL-check at some point (because it is written for a more generic purpose and not use in just this place), then not dropping that NULL-check becomes a very significant missed optimization opportunity.If the compiler wouldn't optimize that out of consideration for the possibility of the former hand-written code, that would incur costs on the programmer. He might have to split do_something_with_ptr() into two functions, one doing NULL checks and one not doing it. He may have to add explicit compiler assumption / unreachability annotations.
The whole argument goes both ways, performing optimizations that break broken code has a cost (people have to fix it) and not performing those optimizations for working code (people have to manually optimize it).
While some compilers do ship with static analysis components (e.g. Clang), static analyzers are usually distinct from compilers. Doesn't matter it for static or dynamic languages.
Every language with a non-trivial number of users tends to have a couple (or maybe couple dozen) different static analyzers of varying quality. This is one of the PHP static analyzers.
This is a very nice article about using epoch-based memory reclamation for lock-free datastructures in Rust: https://aturon.github.io/blog/2015/08/27/epoch/
Lookup of an element. Find the heap with the element (i.e. element between maximum of previous heap and this heap). Perform linear search in heap. Worst cast complexity O(n^(1/3) + n^(2/3)) = O(n^(2/3)).
Insertion of an element. Find the last heap those maximum element is still larger than the element. Extract top element of the heap and insert the new element instead. Then propagate upwards (i.e. extract top of next heap and insert top of previous heap, etc). Worst case is O(n^(1/3) + log(n^(2/3)) * n^(1/3)) = O(log(n) * n^(1/3)).
Deletion of an element. Find the heap with the element (i.e. element between maximum of previous heap and this heap). Remove the element from it. Extract top of next heap and insert it into this one. Then continue propagating upwards. So this is O(n^(1/3) + n^(2/3) + log(n^(2/3)) * n^(1/3)) = O(n^(2/3)).
Building the structure. Why is this O(n)? If you have already segregated the array into segments for the separate heaps, heapifying them would be O(n). How can the segmentation be done in O(n)?
Edit: Using the suggestion of splitting up according to 1+3+5+..+(2n-1) = n^2 we'd get:
Search: O(sqrt(n) + sqrt(n)) = O(sqrt(n))
Insert: O(sqrt(n) + log(sqrt(n)) * sqrt(n)) = O(log(n) * sqrt(n)
Delete: O(sqrt(n) + sqrt(n) + log(sqrt(n)) * sqrt(n)) = O(log(n) * sqrt(n))
My point here is that, in my experience, the main problem of StackOverflow is too little or ineffective moderation, rather than the other way around.
I no longer actively answer questions on StackOverflow, because it is too hard to find worthwhile questions between all the noise. If someone specifically asks me to answer something, I will do it, but trying to find interesting questions on StackOverflow has become impossible due to the high influx of very low quality material.
There was a period where I'd try to help moderation by closing an deleting questions, but at some point you just realize it's a loosing battle and give up.
> Now, the more astute reader will point out that I just sent over 4 gigabytes of data over the internet; and that this can’t really be all that interesting - but that argument is readily countered with gzip encoding, reducing the required data to a 4 megabyte payload.
This was pretty much my first thought on seeing the IOBuffer signature - "That exploit payload is going to be huge". But things are not always as they seem and using gzip to generate a large string on the client is something I had not previously considered.