var createBuiltin = $vm.createBuiltin; var getGetterSetter = $vm.getGetterSetter; function tryGetByIdText(propertyName) { return `(function (base) { return @tryGetById(base, '${propertyName}'); })`; } function tryGetByIdTextStrict(propertyName) { return `(function (base) { "use strict"; return @tryGetById(base, '${propertyName}'); })`; } // Test get value off object. { let get = createBuiltin(tryGetByIdText("caller")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("caller")); noInline(getStrict); let obj = {caller: 1}; for (let i = 0; i < 100000; i++) { if (get(obj) !== 1) throw new Error("wrong on iteration: " + i); if (getStrict(obj) !== 1) throw new Error("wrong on iteration: " + i); } } // Test slot is custom function trap for a value. { let get = createBuiltin(tryGetByIdText("caller")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("caller")); noInline(getStrict); let func = function () {}; for (let i = 0; i < 100000; i++) { if (get(func) !== null) throw new Error("wrong on iteration: " + i); if (getStrict(func) !== null) throw new Error("wrong on iteration: " + i); } } // Test slot is a GetterSetter. { let get = createBuiltin(tryGetByIdText("getterSetter")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("getterSetter")); noInline(getStrict); let obj = {}; Object.defineProperty(obj, "getterSetter", { get: function () { throw new Error("should not be called"); } }); for (let i = 0; i < 100000; i++) { if (get(obj) !== getGetterSetter(obj, "getterSetter")) throw new Error("wrong on iteration: " + i); if (getStrict(obj) !== getGetterSetter(obj, "getterSetter")) throw new Error("wrong on iteration: " + i); } } // Test slot is unset. { let get = createBuiltin(tryGetByIdText("getterSetter")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("getterSetter")); noInline(getStrict); let obj = {}; for (let i = 0; i < 100000; i++) { if (get(obj) !== undefined) throw new Error("wrong on iteration: " + i); if (getStrict(obj) !== undefined) throw new Error("wrong on iteration: " + i); } } // Test slot is on a proxy with value. { let get = createBuiltin(tryGetByIdText("value")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("value")); noInline(getStrict); let obj = {value: 1}; let p = new Proxy(obj, { get: function() { throw new Error("should not be called"); } }); for (let i = 0; i < 100000; i++) { if (get(p) !== null) throw new Error("wrong on iteration: " + i); if (getStrict(p) !== null) throw new Error("wrong on iteration: " + i); } } // Test mutating inline cache. { let get = createBuiltin(tryGetByIdText("caller")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("caller")); noInline(getStrict); let obj = {caller : 1}; let func = function() {}; for (let i = 0; i < 100000; i++) { if (i % 100 === 0) { if (get(func) !== null) throw new Error("wrong on iteration: " + i); if (getStrict(func) !== null) throw new Error("wrong on iteration: " + i); } else { if (get(obj) !== 1) throw new Error("wrong on iteration: " + i); if (getStrict(obj) !== 1) throw new Error("wrong on iteration: " + i); } } } // Test new type on each iteration. { let get = createBuiltin(tryGetByIdText("caller")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("caller")); noInline(getStrict); let func = function() {}; for (let i = 0; i < 100000; i++) { if (i % 100 === 0) { if (get(func) !== null) throw new Error("wrong on iteration: " + i); if (getStrict(func) !== null) throw new Error("wrong on iteration: " + i); } else { let obj = {caller : 1}; if (get(obj) !== 1) throw new Error("wrong on iteration: " + i); if (getStrict(obj) !== 1) throw new Error("wrong on iteration: " + i); } } } // Test with array length. This is null because the value is not cacheable. { let get = createBuiltin(tryGetByIdText("length")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("length")); noInline(getStrict); let arr = []; for (let i = 0; i < 100000; i++) { if (get(arr) !== null) throw new Error("wrong on iteration: " + i); if (getStrict(arr) !== null) throw new Error("wrong on iteration: " + i); } } // Test with non-object. { let get = createBuiltin(tryGetByIdText("length")); noInline(get); let getStrict = createBuiltin(tryGetByIdTextStrict("length")); noInline(getStrict); for (let i = 0; i < 100000; i++) { if (get(1) !== undefined) throw new Error("wrong on iteration: " + i); if (getStrict(1) !== undefined) throw new Error("wrong on iteration: " + i); } }