code: function meta(obj, writable) {
  
        var ret = obj['__ember_meta__'];
        if (writable===false) return ret || EMPTY_META;
  
        if (!ret) {
          if (canDefineNonEnumerableProperties) o_defineProperty(obj, '__ember_meta__', META_DESC);
  
          ret = new Meta(obj);
  
          
            if (hasPropertyAccessors) {
              ret.values = {};
            }
          
  
          obj['__ember_meta__'] = ret;
  
          // make sure we don't accidentally try to create constructor like desc
          ret.descs.constructor = null;
  
        } else if (ret.source !== obj) {
          if (canDefineNonEnumerableProperties) o_defineProperty(obj, '__ember_meta__', META_DESC);
  
          ret = o_create(ret);
          ret.descs     = o_create(ret.descs);
          ret.watching  = o_create(ret.watching);
          ret.cache     = {};
          ret.cacheMeta = {};
          ret.source    = obj;
  
          
            if (hasPropertyAccessors) {
              ret.values = o_create(ret.values);
            }
          
  
          obj['__ember_meta__'] = ret;
        }
        return ret;
      }
docs: Retrieves the meta hash for an object. If `writable` is true ensures the
  hash is writable for this object as well.
  
  The meta object contains information about computed property descriptors as
  well as any watched properties and other information. You generally will
  not access this information directly but instead work with higher level
  methods that manipulate this hash indirectly.
  
  @method meta
  @for Ember
  @private
  
  @param {Object} obj The object to retrieve meta for
  @param {Boolean} [writable=true] Pass `false` if you do not intend to modify
  the meta hash, allowing the method to avoid making an unnecessary copy.
  @return {Object} the meta hash for an object