UNPKG

reign

Version:

A persistent, typed-objects implementation.

140 lines (127 loc) 4.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.make = make; var _integer = require("../../hash-functions/integer"); var _integer2 = _interopRequireDefault(_integer); var _backing = require("backing"); var _backing2 = _interopRequireDefault(_backing); var _ = require("../.."); var _symbols = require("../../symbols"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function make(realm) { const PrimitiveType = realm.PrimitiveType; const Any = new PrimitiveType({ name: 'Any', byteAlignment: 8, byteLength: 12, cast: function cast(input) { // Issue 252 if (typeof input === 'function' || typeof input === 'symbol') { throw new TypeError(`Cannot store values with type: ${ typeof input }`); } else if (input === undefined) { return null; } else { return input; } }, accepts: function accepts(input) { // Issue 252 if (typeof input === 'function' || typeof input === 'symbol') { return false; } else { return true; } }, initialize: function initialize(backing, address, initialValue) { const Type = realm.typeOf(initialValue); let initialAddress; if (Type == null) { backing.setFloat64(address, 0); backing.setUint32(address + 8, 0); } else if (Type.byteLength <= 8) { Type.initialize(backing, address, initialValue); backing.setUint32(address + 8, Type.id); } else if (initialValue[_symbols.$Backing] === backing && (initialAddress = initialValue[_symbols.$Address])) { backing.setFloat64(address, initialAddress); backing.setUint32(address + 8, Type.id); backing.gc.ref(initialAddress); } else { const target = backing.gc.alloc(Type.byteLength, Type.id, 1); Type.initialize(backing, target, initialValue); backing.setFloat64(address, target); backing.setUint32(address + 8, Type.id); } }, store: function store(backing, address, value) { const Type = realm.typeOf(value); const existingTypeId = backing.getUint32(address + 8); if (existingTypeId !== 0) { const existingType = realm.I[existingTypeId]; if (Type != null && existingType === Type && Type.byteLength <= 8) { Type.store(backing, address, value); return; // nothing left to do. } else if (existingType.byteLength <= 8) { existingType.clear(backing, address); } else { const pointer = backing.getFloat64(address); if (pointer !== 0) { backing.gc.unref(pointer); backing.setFloat64(address, 0); // ensures that the value is cleared, even if store fails. } } } let valueAddress; if (Type == null) { backing.setFloat64(address, 0); backing.setUint32(address + 8, 0); } else if (Type.byteLength <= 8) { Type.initialize(backing, address, value); backing.setUint32(address + 8, Type.id); } else if (value[_symbols.$Backing] === backing && (valueAddress = value[_symbols.$Address])) { backing.setFloat64(address, valueAddress); backing.setUint32(address + 8, Type.id); backing.gc.ref(valueAddress); } else { const target = backing.gc.alloc(Type.byteLength, Type.id, 1); Type.initialize(backing, target, value); backing.setFloat64(address, target); backing.setUint32(address + 8, Type.id); } }, load: function load(backing, address) { const typeId = backing.getUint32(address + 8); if (typeId === 0) { return null; } const Type = realm.I[typeId]; if (Type.byteLength <= 8) { return Type.load(backing, address); } const pointer = backing.getFloat64(address); return Type.load(backing, pointer); }, emptyValue: function emptyValue() { return null; }, randomValue: function randomValue() { return null; }, hashValue: function hashValue(input) { const Type = realm.typeOf(input); if (Type == null) { return 4; } else { return Type.hashValue(input); } }, flowType: function flowType() { return `any`; } }); Any[_symbols.$CanBeEmbedded] = true; Any[_symbols.$CanContainReferences] = true; Any[_symbols.$CanBeReferenced] = false; return Any; }