Source code

Revision control

Copy as Markdown

Other Tools

const optionsFull = {
fileName: "compileToStencil-DATA.js",
lineNumber: 1,
eagerDelazificationStrategy: "ParseEverythingEagerly",
};
const optionsLazy = {
fileName: "compileToStencil-DATA.js",
lineNumber: 1,
eagerDelazificationStrategy: "OnDemandOnly",
};
const optionsLazyCache = {
fileName: "compileToStencil-DATA.js",
lineNumber: 1,
eagerDelazificationStrategy: "ConcurrentDepthFirst",
};
const optionsLazyCache2 = {
fileName: "compileToStencil-DATA.js",
lineNumber: 1,
eagerDelazificationStrategy: "ConcurrentLargeFirst",
};
let result = 0;
function testMainThread(script_str) {
const stencil = compileToStencil(script_str, optionsFull);
result = evalStencil(stencil, optionsFull);
assertEq(result, 1);
}
function testMainThreadDelazifyAll(script_str) {
if (isLcovEnabled()) {
// Code-coverage implies forceFullParse = true, and as such it cannot be
// used while testing to incrementally delazify.
return;
}
const stencil = compileToStencil(script_str, optionsLazy);
result = evalStencil(stencil, optionsLazy);
assertEq(result, 1);
}
function testMainThreadCacheAll(script_str) {
if (isLcovEnabled() || helperThreadCount() === 0) {
// Code-coverage implies forceFullParse = true, and as such it cannot be
// used while testing to incrementally delazify.
// Similarly, concurrent delazification requires off-threads processing.
return;
}
const stencil = compileToStencil(script_str, optionsLazyCache);
result = evalStencil(stencil, optionsLazyCache);
assertEq(result, 1);
}
function testMainThreadCacheAll2(script_str) {
if (isLcovEnabled() || helperThreadCount() === 0) {
// Code-coverage implies forceFullParse = true, and as such it cannot be
// used while testing to incrementally delazify.
// Similarly, concurrent delazification requires off-threads processing.
return;
}
const stencil = compileToStencil(script_str, optionsLazyCache2);
result = evalStencil(stencil, optionsLazyCache2);
assertEq(result, 1);
}
function testOffThread(script_str) {
const job = offThreadCompileToStencil(script_str, optionsFull);
const stencil = finishOffThreadStencil(job);
result = evalStencil(stencil, optionsFull);
assertEq(result, 1);
}
// These patches are meant to wrap the inner code given as argument into one
// kind of scope. The freeVars specify one way to retrieve the variable name
// added in this process if any.
const scopeCases = [
{ code: inner => `{ ${inner} }`, freeVars: [] },
{ code: inner => `{ var v = 1; ${inner} }`, freeVars: ["v"] },
{ code: inner => `{ let l = 1; ${inner} }`, freeVars: ["l"] },
{ code: inner => `{ const c = 1; ${inner} }`, freeVars: ["c"] },
{ code: inner => `with ({ p: 1 }) { ${inner} }`, freeVars: ["p"],
inClass: false },
{ code: inner => `(a => { ${inner} })(1)`, freeVars: ["a"] },
{ code: inner => `function fun(a) { ${inner} }; fun(1)`, freeVars: ["a"],
inClass: false},
{ code: inner => `try { ${inner} } catch(unused) { }`, freeVars: [] },
{ code: inner => `try { throw 1; } catch(t) { ${inner} }`, freeVars: ["t"] },
{ code: inner => `{ class C { #m = 1; constructor() { ${inner} }}; new C() }`,
freeVars: ["this.#m"], isClass: true },
];
// This function is used to generate code which mostly exercise the various kind
// of scopes to cover ScopeContext class in CompilationStencil.h
function generateCode(seed) {
let start = inner => `
${inner};
result
`;
let prog = [start];
let freeVars = ["1"];
let inClass = false;
while (seed >= freeVars.length) {
let index = seed % scopeCases.length;
seed = (seed / scopeCases.length) | 0;
let scope = scopeCases[index];
if (inClass && !(scope.inClass ?? false)) {
// Skip illegal code (non-strict) or code which might not accept
// this to work.
continue;
}
inClass ||= scope.isClass ?? false;
prog.push(scope.code);
freeVars = freeVars.concat(scope.freeVars);
}
let name = freeVars[seed];
return prog.reduceRight((inner, f) => f(inner), `result = ${name}`);
}
for (let s = 0; s < 3000; s++) {
let code = generateCode(s);
// console.log(s, ":", code);
testMainThread(code);
testMainThreadDelazifyAll(code);
testMainThreadCacheAll(code);
testMainThreadCacheAll2(code);
if (helperThreadCount() > 0) {
testOffThread(code);
}
}