* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg: any): string;
declare const ArkTools: {
jitCompileAsync(args: any): boolean;
waitJitCompileFinish(args: any): boolean;
};
function testFunctionName(): string {
function namedFunc() {}
const arrowFunc = () => {};
const obj = { method() {} };
return `${namedFunc.name},${arrowFunc.name},${obj.method.name}`;
}
function testFunctionLength(): string {
function f0() {}
function f1(a: number) { return a; }
function f2(a: number, b: number) { return a + b; }
function f3(a: number, b: number, c: number = 0) { return a + b + c; }
return `${f0.length},${f1.length},${f2.length},${f3.length}`;
}
function testFunctionToString(): string {
function add(a: number, b: number) { return a + b; }
const str = add.toString();
return `${str.length > 0},${typeof str === 'string'}`;
}
function testFunctionCall(): string {
function greet(this: { name: string }, greeting: string): string {
return `${greeting}, ${this.name}`;
}
const obj = { name: 'Alice' };
return greet.call(obj, 'Hello');
}
function testFunctionApply(): string {
function sum(a: number, b: number, c: number): number {
return a + b + c;
}
return `${sum.apply(null, [1, 2, 3])}`;
}
function testFunctionCallWithThis(): string {
const obj = {
value: 10,
getValue(this: { value: number }): number {
return this.value;
}
};
const other = { value: 20 };
return `${obj.getValue.call(other)}`;
}
function testFunctionApplyArray(): string {
const arr = [5, 2, 8, 1, 9];
const max = Math.max.apply(null, arr);
const min = Math.min.apply(null, arr);
return `${max},${min}`;
}
function testFunctionBind(): string {
function greet(this: { name: string }): string {
return `Hello, ${this.name}`;
}
const obj = { name: 'Bob' };
const boundGreet = greet.bind(obj);
return boundGreet();
}
function testFunctionBindWithArgs(): string {
function add(a: number, b: number, c: number): number {
return a + b + c;
}
const add5 = add.bind(null, 5);
const add5and10 = add.bind(null, 5, 10);
return `${add5(10, 20)},${add5and10(20)}`;
}
function testFunctionBindChained(): string {
function multiply(a: number, b: number, c: number): number {
return a * b * c;
}
const mult2 = multiply.bind(null, 2);
const mult2by3 = mult2.bind(null, 3);
return `${mult2by3(4)}`;
}
function testClosureBasic(): string {
function outer(x: number) {
return function inner(y: number): number {
return x + y;
};
}
const add10 = outer(10);
return `${add10(5)},${add10(20)}`;
}
function testClosureCounter(): string {
function createCounter() {
let count = 0;
return {
increment(): number { return ++count; },
decrement(): number { return --count; },
getCount(): number { return count; }
};
}
const counter = createCounter();
counter.increment();
counter.increment();
counter.increment();
counter.decrement();
return `${counter.getCount()}`;
}
function testClosurePrivateState(): string {
function createPerson(name: string) {
let _name = name;
return {
getName(): string { return _name; },
setName(newName: string): void { _name = newName; }
};
}
const person = createPerson('Alice');
const initialName = person.getName();
person.setName('Bob');
return `${initialName},${person.getName()}`;
}
function testClosureLoop(): string {
const funcs: (() => number)[] = [];
for (let i = 0; i < 3; i++) {
funcs.push(() => i);
}
return funcs.map(f => f()).join(',');
}
function testHigherOrderMap(): string {
function mapArray<T, U>(arr: T[], fn: (item: T) => U): U[] {
const result: U[] = [];
for (const item of arr) {
result.push(fn(item));
}
return result;
}
const doubled = mapArray([1, 2, 3], x => x * 2);
return doubled.join(',');
}
function testHigherOrderFilter(): string {
function filterArray<T>(arr: T[], predicate: (item: T) => boolean): T[] {
const result: T[] = [];
for (const item of arr) {
if (predicate(item)) result.push(item);
}
return result;
}
const evens = filterArray([1, 2, 3, 4, 5, 6], x => x % 2 === 0);
return evens.join(',');
}
function testHigherOrderReduce(): string {
function reduceArray<T, U>(arr: T[], fn: (acc: U, item: T) => U, initial: U): U {
let acc = initial;
for (const item of arr) {
acc = fn(acc, item);
}
return acc;
}
const sum = reduceArray([1, 2, 3, 4], (acc, x) => acc + x, 0);
return `${sum}`;
}
function testCompose(): string {
function compose<T>(...fns: ((x: T) => T)[]): (x: T) => T {
return (x: T) => fns.reduceRight((acc, fn) => fn(acc), x);
}
const add1 = (x: number) => x + 1;
const mult2 = (x: number) => x * 2;
const sub3 = (x: number) => x - 3;
const composed = compose(add1, mult2, sub3);
return `${composed(5)}`;
}
function testPipe(): string {
function pipe<T>(...fns: ((x: T) => T)[]): (x: T) => T {
return (x: T) => fns.reduce((acc, fn) => fn(acc), x);
}
const add1 = (x: number) => x + 1;
const mult2 = (x: number) => x * 2;
const sub3 = (x: number) => x - 3;
const piped = pipe(add1, mult2, sub3);
return `${piped(5)}`;
}
function testCurryManual(): string {
function curry(fn: (a: number, b: number, c: number) => number) {
return (a: number) => (b: number) => (c: number) => fn(a, b, c);
}
function add(a: number, b: number, c: number): number {
return a + b + c;
}
const curriedAdd = curry(add);
return `${curriedAdd(1)(2)(3)}`;
}
function testPartialApplication(): string {
function partial<T, U, V>(fn: (a: T, b: U) => V, a: T): (b: U) => V {
return (b: U) => fn(a, b);
}
function multiply(a: number, b: number): number {
return a * b;
}
const double = partial(multiply, 2);
const triple = partial(multiply, 3);
return `${double(5)},${triple(5)}`;
}
function testMemoization(): string {
function memoize<T extends (...args: any[]) => any>(fn: T): T {
const cache = new Map<string, any>();
return ((...args: any[]) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
}) as T;
}
let callCount = 0;
const expensive = memoize((n: number) => {
callCount++;
return n * 2;
});
expensive(5);
expensive(5);
expensive(10);
expensive(5);
return `${callCount}`;
}
function testRecursiveFactorial(): string {
function factorial(n: number): number {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
return `${factorial(5)},${factorial(0)},${factorial(1)}`;
}
function testRecursiveFibonacci(): string {
function fib(n: number): number {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
return `${fib(0)},${fib(1)},${fib(5)},${fib(10)}`;
}
function testTailRecursion(): string {
function factorialTail(n: number, acc: number = 1): number {
if (n <= 1) return acc;
return factorialTail(n - 1, n * acc);
}
return `${factorialTail(5)}`;
}
function testIIFE(): string {
const result = ((x: number) => x * 2)(5);
return `${result}`;
}
function testIIFEWithState(): string {
const counter = (() => {
let count = 0;
return {
inc(): number { return ++count; },
get(): number { return count; }
};
})();
counter.inc();
counter.inc();
return `${counter.get()}`;
}
function testArrowThis(): string {
const obj = {
value: 42,
getValueArrow: function() {
const arrow = () => this.value;
return arrow();
}
};
return `${obj.getValueArrow()}`;
}
function testArrowNoArguments(): string {
function regular(...args: number[]): number[] {
const arrow = () => args;
return arrow();
}
return regular(1, 2, 3).join(',');
}
function testDefaultParams(): string {
function greet(name: string = 'World', greeting: string = 'Hello'): string {
return `${greeting}, ${name}`;
}
return `${greet()},${greet('Alice')},${greet('Bob', 'Hi')}`;
}
function testDefaultParamsExpression(): string {
function createArray(size: number = 3, fill: number = size * 2): number[] {
return new Array(size).fill(fill);
}
return `${createArray().join(',')},${createArray(2).join(',')}`;
}
function testRestParams(): string {
function sum(...numbers: number[]): number {
return numbers.reduce((a, b) => a + b, 0);
}
return `${sum(1, 2, 3)},${sum(1, 2, 3, 4, 5)}`;
}
function testRestWithRequired(): string {
function format(prefix: string, ...values: number[]): string {
return `${prefix}: ${values.join(', ')}`;
}
return format('Numbers', 1, 2, 3);
}
function testGeneratorBasic(): string {
function* gen(): Generator<number> {
yield 1;
yield 2;
yield 3;
}
return [...gen()].join(',');
}
function testGeneratorWithReturn(): string {
function* gen(): Generator<number, string> {
yield 1;
yield 2;
return 'done';
}
const g = gen();
const results: string[] = [];
let result = g.next();
while (!result.done) {
results.push(String(result.value));
result = g.next();
}
results.push(result.value);
return results.join(',');
}
function testFunctionAsObject(): string {
function fn() {}
fn.customProp = 'value';
(fn as any).counter = 0;
return `${(fn as any).customProp},${(fn as any).counter}`;
}
for (let i = 0; i < 20; i++) {
testFunctionName();
testFunctionLength();
testFunctionToString();
testFunctionCall();
testFunctionApply();
testFunctionCallWithThis();
testFunctionApplyArray();
testFunctionBind();
testFunctionBindWithArgs();
testFunctionBindChained();
testClosureBasic();
testClosureCounter();
testClosurePrivateState();
testClosureLoop();
testHigherOrderMap();
testHigherOrderFilter();
testHigherOrderReduce();
testCompose();
testPipe();
testCurryManual();
testPartialApplication();
testMemoization();
testRecursiveFactorial();
testRecursiveFibonacci();
testTailRecursion();
testIIFE();
testIIFEWithState();
testArrowThis();
testArrowNoArguments();
testDefaultParams();
testDefaultParamsExpression();
testRestParams();
testRestWithRequired();
testGeneratorBasic();
testGeneratorWithReturn();
testFunctionAsObject();
}
ArkTools.jitCompileAsync(testFunctionName);
ArkTools.jitCompileAsync(testFunctionLength);
ArkTools.jitCompileAsync(testFunctionToString);
ArkTools.jitCompileAsync(testFunctionCall);
ArkTools.jitCompileAsync(testFunctionApply);
ArkTools.jitCompileAsync(testFunctionCallWithThis);
ArkTools.jitCompileAsync(testFunctionApplyArray);
ArkTools.jitCompileAsync(testFunctionBind);
ArkTools.jitCompileAsync(testFunctionBindWithArgs);
ArkTools.jitCompileAsync(testFunctionBindChained);
ArkTools.jitCompileAsync(testClosureBasic);
ArkTools.jitCompileAsync(testClosureCounter);
ArkTools.jitCompileAsync(testClosurePrivateState);
ArkTools.jitCompileAsync(testClosureLoop);
ArkTools.jitCompileAsync(testHigherOrderMap);
ArkTools.jitCompileAsync(testHigherOrderFilter);
ArkTools.jitCompileAsync(testHigherOrderReduce);
ArkTools.jitCompileAsync(testCompose);
ArkTools.jitCompileAsync(testPipe);
ArkTools.jitCompileAsync(testCurryManual);
ArkTools.jitCompileAsync(testPartialApplication);
ArkTools.jitCompileAsync(testMemoization);
ArkTools.jitCompileAsync(testRecursiveFactorial);
ArkTools.jitCompileAsync(testRecursiveFibonacci);
ArkTools.jitCompileAsync(testTailRecursion);
ArkTools.jitCompileAsync(testIIFE);
ArkTools.jitCompileAsync(testIIFEWithState);
ArkTools.jitCompileAsync(testArrowThis);
ArkTools.jitCompileAsync(testArrowNoArguments);
ArkTools.jitCompileAsync(testDefaultParams);
ArkTools.jitCompileAsync(testDefaultParamsExpression);
ArkTools.jitCompileAsync(testRestParams);
ArkTools.jitCompileAsync(testRestWithRequired);
ArkTools.jitCompileAsync(testGeneratorBasic);
ArkTools.jitCompileAsync(testGeneratorWithReturn);
ArkTools.jitCompileAsync(testFunctionAsObject);
print("compile testFunctionName: " + ArkTools.waitJitCompileFinish(testFunctionName));
print("compile testFunctionLength: " + ArkTools.waitJitCompileFinish(testFunctionLength));
print("compile testFunctionToString: " + ArkTools.waitJitCompileFinish(testFunctionToString));
print("compile testFunctionCall: " + ArkTools.waitJitCompileFinish(testFunctionCall));
print("compile testFunctionApply: " + ArkTools.waitJitCompileFinish(testFunctionApply));
print("compile testFunctionCallWithThis: " + ArkTools.waitJitCompileFinish(testFunctionCallWithThis));
print("compile testFunctionApplyArray: " + ArkTools.waitJitCompileFinish(testFunctionApplyArray));
print("compile testFunctionBind: " + ArkTools.waitJitCompileFinish(testFunctionBind));
print("compile testFunctionBindWithArgs: " + ArkTools.waitJitCompileFinish(testFunctionBindWithArgs));
print("compile testFunctionBindChained: " + ArkTools.waitJitCompileFinish(testFunctionBindChained));
print("compile testClosureBasic: " + ArkTools.waitJitCompileFinish(testClosureBasic));
print("compile testClosureCounter: " + ArkTools.waitJitCompileFinish(testClosureCounter));
print("compile testClosurePrivateState: " + ArkTools.waitJitCompileFinish(testClosurePrivateState));
print("compile testClosureLoop: " + ArkTools.waitJitCompileFinish(testClosureLoop));
print("compile testHigherOrderMap: " + ArkTools.waitJitCompileFinish(testHigherOrderMap));
print("compile testHigherOrderFilter: " + ArkTools.waitJitCompileFinish(testHigherOrderFilter));
print("compile testHigherOrderReduce: " + ArkTools.waitJitCompileFinish(testHigherOrderReduce));
print("compile testCompose: " + ArkTools.waitJitCompileFinish(testCompose));
print("compile testPipe: " + ArkTools.waitJitCompileFinish(testPipe));
print("compile testCurryManual: " + ArkTools.waitJitCompileFinish(testCurryManual));
print("compile testPartialApplication: " + ArkTools.waitJitCompileFinish(testPartialApplication));
print("compile testMemoization: " + ArkTools.waitJitCompileFinish(testMemoization));
print("compile testRecursiveFactorial: " + ArkTools.waitJitCompileFinish(testRecursiveFactorial));
print("compile testRecursiveFibonacci: " + ArkTools.waitJitCompileFinish(testRecursiveFibonacci));
print("compile testTailRecursion: " + ArkTools.waitJitCompileFinish(testTailRecursion));
print("compile testIIFE: " + ArkTools.waitJitCompileFinish(testIIFE));
print("compile testIIFEWithState: " + ArkTools.waitJitCompileFinish(testIIFEWithState));
print("compile testArrowThis: " + ArkTools.waitJitCompileFinish(testArrowThis));
print("compile testArrowNoArguments: " + ArkTools.waitJitCompileFinish(testArrowNoArguments));
print("compile testDefaultParams: " + ArkTools.waitJitCompileFinish(testDefaultParams));
print("compile testDefaultParamsExpression: " + ArkTools.waitJitCompileFinish(testDefaultParamsExpression));
print("compile testRestParams: " + ArkTools.waitJitCompileFinish(testRestParams));
print("compile testRestWithRequired: " + ArkTools.waitJitCompileFinish(testRestWithRequired));
print("compile testGeneratorBasic: " + ArkTools.waitJitCompileFinish(testGeneratorBasic));
print("compile testGeneratorWithReturn: " + ArkTools.waitJitCompileFinish(testGeneratorWithReturn));
print("compile testFunctionAsObject: " + ArkTools.waitJitCompileFinish(testFunctionAsObject));
print("testFunctionName: " + testFunctionName());
print("testFunctionLength: " + testFunctionLength());
print("testFunctionToString: " + testFunctionToString());
print("testFunctionCall: " + testFunctionCall());
print("testFunctionApply: " + testFunctionApply());
print("testFunctionCallWithThis: " + testFunctionCallWithThis());
print("testFunctionApplyArray: " + testFunctionApplyArray());
print("testFunctionBind: " + testFunctionBind());
print("testFunctionBindWithArgs: " + testFunctionBindWithArgs());
print("testFunctionBindChained: " + testFunctionBindChained());
print("testClosureBasic: " + testClosureBasic());
print("testClosureCounter: " + testClosureCounter());
print("testClosurePrivateState: " + testClosurePrivateState());
print("testClosureLoop: " + testClosureLoop());
print("testHigherOrderMap: " + testHigherOrderMap());
print("testHigherOrderFilter: " + testHigherOrderFilter());
print("testHigherOrderReduce: " + testHigherOrderReduce());
print("testCompose: " + testCompose());
print("testPipe: " + testPipe());
print("testCurryManual: " + testCurryManual());
print("testPartialApplication: " + testPartialApplication());
print("testMemoization: " + testMemoization());
print("testRecursiveFactorial: " + testRecursiveFactorial());
print("testRecursiveFibonacci: " + testRecursiveFibonacci());
print("testTailRecursion: " + testTailRecursion());
print("testIIFE: " + testIIFE());
print("testIIFEWithState: " + testIIFEWithState());
print("testArrowThis: " + testArrowThis());
print("testArrowNoArguments: " + testArrowNoArguments());
print("testDefaultParams: " + testDefaultParams());
print("testDefaultParamsExpression: " + testDefaultParamsExpression());
print("testRestParams: " + testRestParams());
print("testRestWithRequired: " + testRestWithRequired());
print("testGeneratorBasic: " + testGeneratorBasic());
print("testGeneratorWithReturn: " + testGeneratorWithReturn());
print("testFunctionAsObject: " + testFunctionAsObject());