text: 'use strict';
  
  var GetIntrinsic = require('../GetIntrinsic');
  
  var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%');
  var $TypeError = GetIntrinsic('%TypeError%');
  
  var callBound = require('../helpers/callBound');
  
  var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');
  
  var has = require('has');
  
  var IsArray = require('./IsArray');
  var IsPropertyKey = require('./IsPropertyKey');
  var IsRegExp = require('./IsRegExp');
  var ToPropertyDescriptor = require('./ToPropertyDescriptor');
  var Type = require('./Type');
  
  // https://www.ecma-international.org/ecma-262/6.0/#sec-ordinarygetownproperty
  
  module.exports = function OrdinaryGetOwnProperty(O, P) {
  	if (Type(O) !== 'Object') {
  		throw new $TypeError('Assertion failed: O must be an Object');
  	}
  	if (!IsPropertyKey(P)) {
  		throw new $TypeError('Assertion failed: P must be a Property Key');
  	}
  	if (!has(O, P)) {
  		return void 0;
  	}
  	if (!$gOPD) {
  		// ES3 fallback
  		var arrayLength = IsArray(O) && P === 'length';
  		var regexLastIndex = IsRegExp(O) && P === 'lastIndex';
  		return {
  			'[[Configurable]]': !(arrayLength || regexLastIndex),
  			'[[Enumerable]]': $isEnumerable(O, P),
  			'[[Value]]': O[P],
  			'[[Writable]]': true
  		};
  	}
  	return ToPropertyDescriptor($gOPD(O, P));
  };
  