mirror of
https://github.com/tc39/test262.git
synced 2025-05-04 15:00:42 +02:00
* [javascriptcore-test262-automation] changes from git@github.com:WebKit/webkit.git at sha 949e26452cfa153a7f4afe593da97e2fe9e1b706 on Tue Jul 03 2018 14:35:15 GMT-0400 (Eastern Daylight Time)
208 lines
4.3 KiB
JavaScript
208 lines
4.3 KiB
JavaScript
"use strict";
|
|
|
|
var createCustomGetterObject = $vm.createCustomGetterObject;
|
|
|
|
function assert(a) {
|
|
if (!a)
|
|
throw new Error("Bad!");
|
|
}
|
|
|
|
var Base = class Base {
|
|
constructor() { this._name = "Name"; }
|
|
get name() { return this._name; } // If this instead returns a static: return "Foo" things somewhat work.
|
|
set name(x) { this._name = x; }
|
|
};
|
|
|
|
var Subclass = class Subclass extends Base {
|
|
get name() { return super.name; }
|
|
};
|
|
|
|
function getterName(instance) {
|
|
return instance.name;
|
|
}
|
|
|
|
noInline(getterName);
|
|
|
|
function getterValue(instance) {
|
|
return instance.value;
|
|
}
|
|
|
|
noInline(getterValue);
|
|
|
|
const runTimes = 10000;
|
|
|
|
// Base case
|
|
var instance = new Subclass;
|
|
for (let i = 0; i < runTimes; i++)
|
|
assert(getterName(instance) == "Name");
|
|
|
|
// Polymorphic case
|
|
|
|
class PolymorphicSubclass {
|
|
get value() { return super.value; }
|
|
};
|
|
|
|
let numPolymorphicClasses = 4;
|
|
let subclasses = new Array(numPolymorphicClasses);
|
|
for (let i = 0; i < numPolymorphicClasses; i++) {
|
|
let BaseCode = `
|
|
(class Base${i} {
|
|
get value() { return this._value; }
|
|
});
|
|
`;
|
|
|
|
let Base = eval(BaseCode);
|
|
subclasses[i] = new PolymorphicSubclass();
|
|
subclasses[i]._value = i;
|
|
|
|
Object.setPrototypeOf(subclasses[i], Base.prototype);
|
|
}
|
|
|
|
for (let i = 0; i < runTimes; i++) {
|
|
let index = i % numPolymorphicClasses;
|
|
let value = getterValue(subclasses[index]);
|
|
assert(value == index);
|
|
}
|
|
|
|
// Megamorphic case
|
|
|
|
let nClasses = 1000;
|
|
class MegamorphicSubclass {
|
|
get value() { return super.value; }
|
|
};
|
|
|
|
subclasses = new Array(nClasses);
|
|
for (let i = 0; i < nClasses; i++) {
|
|
let BaseCode = `
|
|
(class Base${i + 4} {
|
|
get value() { return this._value; }
|
|
});
|
|
`;
|
|
|
|
let Base = eval(BaseCode);
|
|
subclasses[i] = new MegamorphicSubclass();
|
|
subclasses[i]._value = i;
|
|
|
|
Object.setPrototypeOf(subclasses[i], Base.prototype);
|
|
}
|
|
|
|
for (let i = 0; i < runTimes; i++) {
|
|
let index = i % nClasses;
|
|
let value = getterValue(subclasses[index]);
|
|
assert(value == index);
|
|
}
|
|
|
|
// CustomGetter case
|
|
|
|
let customGetter = createCustomGetterObject();
|
|
Object.setPrototypeOf(customGetter, Object.prototype);
|
|
|
|
let subObj = {
|
|
__proto__: customGetter,
|
|
get value () {
|
|
return super.customGetterAccessor;
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < runTimes; i++) {
|
|
let value = getterValue(subObj);
|
|
assert(value == 100);
|
|
}
|
|
|
|
subObj.shouldThrow = true;
|
|
for (let i = 0; i < runTimes; i++) {
|
|
try {
|
|
getterValue(subObj);
|
|
assert(false);
|
|
} catch(e) {
|
|
assert(e instanceof TypeError);
|
|
};
|
|
}
|
|
|
|
// CustomValue case
|
|
|
|
customGetter = createCustomGetterObject();
|
|
Object.setPrototypeOf(customGetter, Object.prototype);
|
|
|
|
subObj = {
|
|
__proto__: customGetter,
|
|
get value () {
|
|
return super.customGetter;
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < runTimes; i++) {
|
|
let value = getterValue(subObj);
|
|
assert(value == 100);
|
|
}
|
|
|
|
subObj.shouldThrow = true;
|
|
for (let i = 0; i < runTimes; i++) {
|
|
let value = getterValue(subObj);
|
|
assert(value == 100);
|
|
}
|
|
|
|
// Exception handling case
|
|
|
|
class BaseException {
|
|
constructor() { this._name = "Name"; }
|
|
get name() {
|
|
if (this.shouldThrow)
|
|
throw new Error("Forced Exception");
|
|
return this._name;
|
|
}
|
|
};
|
|
|
|
class SubclassException extends BaseException {
|
|
get name() { return super.name; }
|
|
};
|
|
|
|
let eObj = new SubclassException;
|
|
for (let i = 0; i < runTimes; i++)
|
|
assert(getterName(eObj) == "Name");
|
|
|
|
eObj.shouldThrow = true;
|
|
for (let i = 0; i < runTimes; i++) {
|
|
try {
|
|
getterValue(eObj);
|
|
assert(false);
|
|
} catch(e) {
|
|
eObj.shouldThrow = false;
|
|
assert(getterName(eObj) == "Name");
|
|
};
|
|
}
|
|
|
|
// In getter exception handling
|
|
|
|
class BaseExceptionComplex {
|
|
constructor() { this._name = "Name"; }
|
|
foo () {
|
|
if (this.shouldThrow)
|
|
throw new Error("Forced Exception");
|
|
}
|
|
get name() {
|
|
this.foo();
|
|
return this._name;
|
|
}
|
|
};
|
|
|
|
class SubclassExceptionComplex extends BaseExceptionComplex {
|
|
get name() {
|
|
try {
|
|
return super.name;
|
|
} catch(e) {
|
|
this.shouldThrow = false;
|
|
return super.name;
|
|
}
|
|
}
|
|
};
|
|
|
|
eObj = new SubclassExceptionComplex;
|
|
for (let i = 0; i < runTimes; i++)
|
|
assert(getterName(eObj) == "Name");
|
|
|
|
eObj.shouldThrow = true;
|
|
for (let i = 0; i < runTimes; i++)
|
|
assert(getterName(eObj) == "Name");
|
|
|