# 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: ```bash # compilation of separate module and library ./bin/es2panda --extension=sts --output=out.abc --opt-level=2 x.sts ./bin/es2panda --extension=sts --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._$init$_()* 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._$init$_()* 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: ```bash # 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: ```bash ./bin/es2panda --extension=sts --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.sts 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. ```bash ./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: ```typescript 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: ```json { "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"] }, "dynamicPaths": { "dynamic_js_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: ```bash ./bin/es2panda --extension=sts --output=out.abc --opt-level=2 --gen-stdlib=false \ --arktsconfig=/path/to/arktsconfig.json x.sts ``` ### 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. ```bash ./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.: ```cpp 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.sts* file which can be generated by: ```bash 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