RFC: Native Property Handlers

Summary: Fixes #4100

==Problem==

We have a lot of cases [1] when user-level classes extend some native classes, and after implementing magic methods like `__get`, `__set`, etc in the child classes, some native properties which are implemented in the base classes with the same `__get` become broken. Users have to call `parent::__get` in order to retrieve correct value.

The problem details are described in [2].

This diff stratifies implementation-level and user-level handling of magic properties.

[1] https://github.com/facebook/hhvm/issues/4100#issuecomment-61378662
[2] https://www.prod.facebook.com/groups/hhvm.dev/permalink/306537302868709/

==Design notes==

- Native handling of the magic properties is done via "PropHandler" classes. A prop handler class corresponds to its actual class, and should be registered for the actual class name. Example:

  // Define prop handler for the `Element` class

  class ElementPropHandler {
    static Variant getProp(ObjectData* this_, const StringData* name) {
      // get `name` prop
    }
  }

- The default registering of the handler is done providing the handler and the actual classes. In this case the handler class implements all the accessor hooks:

  // Register the handler.
  Native::registerNativePropHandler<ElemntPropHandler>(s_ElementClass.get());

- It is possible to register the handler with custom handling callbacks.

  Native::registerNativePropHandler(s_ElementClass.get()
                                    &customGetProp,
                                    &customSetProp
                                    ...);

- At property resolution (in `object-data.cpp`) the caller invokes generic `Native::getProp` passing the object data (`this` value), and the prop name:

  Native::getProp(this, propName);

Note: In the `object-data.cpp` I've implemented only for getProp yet. Will add others (set, isset, unset, dim) after initial review.

Reviewed By: @paulbiss

Differential Revision: D1669546