The cheat sheet for ArkTS frontend
How to compile a module
At the beginning, need to define what we want to compile. There are three kinds of compilation units:
- Separate modules
- Declaration modules
- Packages
(For more information, see ArkTS spec 13 chapter) In any case, regardless of whether we have an entry point or not, the compilation and execution commands will be the same and look like this:
# compilation of separate module and library
./bin/es2panda --extension=ets --output=out.abc --opt-level=2 x.ets
./bin/es2panda --extension=ets --output=etsstdlib.abc --opt-level=2 --gen-stdlib=true
# execution command
./bin/ark --boot-panda-files=etsstdlib.abc --load-runtimes=ets out.abc ETSGLOBAL::main
More details about separate modules, conceptually:
- A separate module can have an entry point (be a program) or be a module with no entry point which can be imported and used as a kind of library
- If a module has an entry point then
Entry_point := ArkTS_main | ArkTS_top-level-statements | ArkTS_top-level-statements ArkTS_main - 3 options
Thus, Runtime_main () {
if (ArkTS_top_level_statements_in_place) call ArkTS_top-level-statements // 1st step
if (ArkTS_main_in_place) call ArkTS_main // 2nd step
} // Case, when both are missed, should never happen - guaranteed by front-end and code generation
In practice:
For the 1st step all top-level statements (see spec 13.8 point) will be placed inside
ETSGLOBAL.initinit() function which is called inside ETSGLOBAL.cctor().
For the 2nd step we just always generate ETSGLOBAL.main() function and call after
constructor for ETSGLOBAL. But also ETSGLOBAL.initinit() can be called as a consequence of main call.
Note1: main entrypoint method is possibly synthetic and always exists actually.
Note2: Package modules are not fully supported, see #16267 internal issue.
How to execute a module
The process of program execution on our VM is the same in all cases. To execute compiled module out.abc we have several options:
# Interpreter
./bin/ark --compiler-enable-jit=false --boot-panda-files=etsstdlib.abc \
--load-runtimes=ets out.abc ETSGLOBAL::main
# JIT
./bin/ark --compiler-enable-jit=true --boot-panda-files=etsstdlib.abc \
--load-runtimes=ets out.abc ETSGLOBAL::main
# AOT - 2 steps
./bin/ark_aot --boot-panda-files=etsstdlib.abc --load-runtimes=ets \
--paoc-panda-files out.abc --paoc-output out.aot
./bin/ark --boot-panda-files=etsstdlib.abc --load-runtimes=ets \
--aot-files=out.aot out.abc ETSGLOBAL::main
Some additional options that can be helpful:
- --no-async-jit
- --compiler-hotness-threshold=0 (to initiate jit compilation on the first method call) For more details see ./bin/ark --help.
How to compile a library module
The library module is compiled the same way as a regular module:
./bin/es2panda --extension=ets --output=out.abc --opt-level=2 --gen-stdlib=false /path/to/module/folder
Notes:
- Standard library is an implicit import as defined in spec 13.5 point. As for now it's imported via arktsconfig.json file. This file is generated by cmake in the path/to/build/tools/es2panda/generated/ folder. It has 2 default paths related to stdlib - std and compat. They're imported in each module that we compile.
- Package modules are not fully supported, see #16267 internal issue.
How to use .abc and .d.ets without samples
todo
How to find out what is in .abc
To see what entities were generated by es2panda, we have ark_disasm tool. Its input is .abc file, its output is .pa (panda assembler) file.
./bin/ark_disasm out.abc out.pa
It shows all functions, instructions, records, also their flags, access modifiers and external/internal marks.
How package names are involved in the program
Package names become a prefix of all entities declared in a package. For example, if we have such code:
package P1
function foo() {}
The foo name in the bytecode will be P1.ETSGLOBAL.foo. Note: For now we have some problems with generating names for packages
About —global-module-prefix option
todo
How does global scope affect .abc
todo
What is available without importing
Implicit import is defined in spec 13.5 point. In details, we have arktsconfig.json file. This file is generated by cmake in the path/to/build/tools/es2panda/generated/ folder. It has 2 default paths related to stdlib - std and compat. They're imported in each module that we compile. The default config file looks like this:
{
"compilerOptions": {
"baseUrl": "/path/to/static_core",
"paths": {
"std": ["/path/to/static_core/plugins/ets/stdlib/std"],
"escompat": ["/path/to/static_core/plugins/ets/stdlib/escompat"],
"import_tests": ["/path/to/static_core/tools/es2panda/test/parser/ets/import_tests"],
"dynamic_import_tests": ["/path/to/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests"]
},
"dependencies": {
"dynamic_import_tests": {"language": "js", "hasDecl": false},
"/path/to/static_core/tools/es2panda/test/parser/ets/dynamic_import_tests": {"language": "js", "hasDecl": true}
}
}
}
In additional, implicitly imported paths can be added. After that, your custom config file should be passed to the appropriate option:
./bin/es2panda --extension=ets --output=out.abc --opt-level=2 --gen-stdlib=false \
--arktsconfig=/path/to/arktsconfig.json x.ets
How to make one .abc file from two
Tool ark_link can do it. Need to pass an arbitrary number of files as arguments to this application and it will output a combined .abc file.
./bin/ark_link --output out.abc -- a.abc b.abc
Note: Be aware of redefinition.
How to connect the native .so
Have 2 options to form a correct .so for further work with it:
- Need to register all the functions that will be called from ts on the native side. How to do this - see the file peer_lib/cpp/arkts/convertors-ark.cc/convertors-ark.cc from the https://gitee.com/nikolay-igotti/idlize/ repo
- Register through the construction: "ETS_EXPORT ets_"return type" ETS_CALL ETS_classname_methodname(EtsEnv *, args) {..}", e.g.:
extern "C" ETS_EXPORT ets_int ETS_CALL EtsNapiOnLoad(EtsEnv *env) {
if (!registerNatives(env, env->FindClass("NativeModule.NativeModule"))) return -1;
return ETS_NAPI_VERSION_1_0;
}
How to execute program with native .so
Need to write loadLibrary("name of the .so") in the right place on the ts side. An example can be found in NativeModule.ets file which can be generated by:
npm panda:sdk:install
arkts:make
Finally, need to execute with LD_LIBRARY_PATH=/path/to/directory/with/so passed to ark, so that the code that loads the lib will see it.
How to connect interop with dynamic js vm
todo
What are the limits of the internal keyword? One .abc? One module?
todo
How to run multi-module programm?
//x.ets
import { foo } from "./y.ets"
function main () {
console.log(foo())
}
//y.ets
export function foo(): int {return 54}
# compilation of separate module
./bin/es2panda --extension=ets --output=b.abc --opt-level=2 --ets-module y.ets
./bin/es2panda --extension=ets --output=a.abc --opt-level=2 x.ets
# linkage of binary files
./bin/ark_link --output out.abc -- a.abc b.abc
# execution command
./bin/ark --boot-panda-files=etsstdlib.abc --load-runtimes=ets out.abc ETSGLOBAL::main