├── .gitignore ├── CMakeLists.txt ├── ChangeLog ├── LICENSE.TXT ├── README ├── README.md ├── include └── client │ ├── README.md │ ├── client.h │ ├── clientlib.h │ ├── coroutine.h │ ├── function.h │ ├── jsexception.h │ ├── jshelper.h │ ├── jsobject.h │ ├── memory.h │ ├── new │ ├── cheerp_utility.h │ ├── client.h │ ├── clientlib.h │ ├── coroutine.h │ ├── function.h │ ├── jsexception.h │ ├── jshelper.h │ ├── jsobject.h │ ├── memory.h │ ├── types.h │ └── webgl.h │ ├── old │ ├── client.h │ ├── clientlib.h │ ├── jsexception.h │ ├── jsobject.h │ ├── memory.h │ ├── types.h │ └── webgl.h │ ├── types.h │ └── webgl.h ├── scripts ├── cheerp-unknown-none-g++ ├── cheerp-unknown-none-gcc ├── cheerpwrap.in ├── wasm32-unknown-none-g++ ├── wasm32-unknown-none-gcc ├── wasm32-unknown-wasi-g++ └── wasm32-unknown-wasi-gcc ├── tests ├── .gitignore ├── Makefile ├── check_dts │ ├── .gitignore │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── dom │ ├── Makefile │ ├── dom1.cpp │ ├── dom2.cpp │ ├── test1.html │ └── test2.html ├── emscripten_tests │ ├── Makefile │ ├── benchmark.sh │ ├── copy.cpp │ ├── corrections.cpp │ ├── fannkuch.cpp │ ├── fasta.cpp │ ├── memops.cpp │ └── primes.cpp ├── frontend │ └── ffi │ │ ├── func_arg_func.cpp │ │ ├── func_arg_str.cpp │ │ ├── func_arg_variadic.cpp │ │ └── func_args.cpp ├── import-polyfills.js ├── run_tests.py ├── tests.make ├── unit │ ├── anyref │ │ └── args.cpp │ ├── bitfield │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ └── test5.cpp │ ├── cli │ │ ├── argv.cpp │ │ ├── argv.testing.js │ │ ├── env.cpp │ │ └── env.testing.js │ ├── client │ │ ├── _delete.cpp │ │ ├── _delete.testing.js │ │ ├── class.cpp │ │ ├── globals.cpp │ │ ├── globals.testing.js │ │ ├── instanceof.cpp │ │ ├── nested-namespaces.cpp │ │ ├── setter-getter.cpp │ │ ├── static-methods.cpp │ │ └── typeof.cpp │ ├── closures │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ └── test4.cpp │ ├── codegen │ │ ├── 64bitenum.cpp │ │ ├── 64bitpointerarith.cpp │ │ ├── 64bitrewrite.cpp │ │ ├── abs.cpp │ │ ├── advancedasm.cpp │ │ ├── bswap.cpp │ │ ├── byval.cpp │ │ ├── covariant-pa.cpp │ │ ├── dynalloca.cpp │ │ ├── dynstack.cpp │ │ ├── escapes.cpp │ │ ├── floattoint.cpp │ │ ├── fptoi.cpp │ │ ├── nested_lambda.cpp │ │ ├── reverse_iter.cpp │ │ ├── structbase.cpp │ │ ├── test1.cpp │ │ ├── test10.cpp │ │ ├── test11.cpp │ │ ├── test12.cpp │ │ ├── test13.cpp │ │ ├── test14.cpp │ │ ├── test15.cpp │ │ ├── test16.cpp │ │ ├── test17.cpp │ │ ├── test18.cpp │ │ ├── test19.cpp │ │ ├── test2.cpp │ │ ├── test20.cpp │ │ ├── test21.cpp │ │ ├── test22.cpp │ │ ├── test23.cpp │ │ ├── test24.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ ├── test5.cpp │ │ ├── test6.cpp │ │ ├── test7.cpp │ │ ├── test8.cpp │ │ ├── test9.cpp │ │ ├── unsignedTrunc.cpp │ │ ├── unsignedTrunc.testing.js │ │ └── variadic.cpp │ ├── coroutines │ │ ├── cast-promise.cpp │ │ └── test1.cpp │ ├── dom │ │ ├── max.cpp │ │ ├── noconstructor.cpp │ │ ├── objapi.cpp │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ ├── test5.cpp │ │ ├── test6.cpp │ │ ├── test7.cpp │ │ ├── test8.cpp │ │ ├── test9.cpp │ │ └── utf8.cpp │ ├── downcast │ │ └── test1.cpp │ ├── exceptions │ │ ├── test1.cpp │ │ └── test2.cpp │ ├── ffi │ │ ├── i64.cpp │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ └── test3.cpp │ ├── globals │ │ ├── betterconst.cpp │ │ ├── globaluint16.cpp │ │ ├── initializers.cpp │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ ├── test5.cpp │ │ ├── test6.cpp │ │ └── test7.cpp │ ├── jsexport │ │ ├── array_of_structs.cpp │ │ ├── array_of_structs.testing.js │ │ ├── cat.cpp │ │ ├── cat.testing.js │ │ ├── cheerp_pimpl.cpp │ │ ├── cheerp_pimpl.h │ │ ├── cheerp_pimpl_mod.cpp │ │ ├── cheerp_pimpl_mod.testing.js │ │ ├── compare_pointers.cpp │ │ ├── compare_pointers.testing.js │ │ ├── empty_class.cpp │ │ ├── empty_class.testing.js │ │ ├── factory.cpp │ │ ├── global_variables.cpp │ │ ├── global_variables.testing.js │ │ ├── inheritance.cpp │ │ ├── inheritance.testing.js │ │ ├── invoke_functions.cpp │ │ ├── member_variables.cpp │ │ ├── member_variables.testing.js │ │ ├── namespaces.cpp │ │ ├── nested_variables.cpp │ │ ├── nested_variables.testing.js │ │ ├── parameters_builtin.cpp │ │ ├── parameters_client.cpp │ │ ├── qualifiers.cpp │ │ ├── static_variables.cpp │ │ ├── static_variables.testing.js │ │ ├── unsafe_clang.cpp │ │ └── unsafe_gnu.c │ ├── memory │ │ ├── arraynew.cpp │ │ ├── kinds.cpp │ │ ├── multiarray.cpp │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ ├── test5.cpp │ │ ├── test6.cpp │ │ ├── test7.cpp │ │ ├── test8.cpp │ │ ├── typed_memintrinsics.cpp │ │ └── typedarrays_operator.cpp │ ├── randomcfg │ │ ├── comb10by10.cpp │ │ ├── comb25by25.cpp │ │ ├── combOnDouble.cpp │ │ ├── operationsOnInt64.cpp │ │ ├── size10times10.cpp │ │ ├── size20times10.cpp │ │ ├── size50times2.cpp │ │ ├── size5times20.cpp │ │ ├── swap10by10.cpp │ │ ├── swap25by25.cpp │ │ ├── swap5by5.cpp │ │ └── swapOnPointers.cpp │ ├── static │ │ └── test1.cpp │ ├── std │ │ ├── chrono.cpp │ │ ├── gettimeofday.cpp │ │ ├── locale.cpp │ │ ├── malloc.cpp │ │ ├── mapdestruction.cpp │ │ ├── memcmp.cpp │ │ ├── sort.cpp │ │ ├── sscanf.cpp │ │ ├── stdmemfuncs.cpp │ │ ├── stringassign.cpp │ │ ├── stringhashing.cpp │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ ├── test5.cpp │ │ ├── test6.cpp │ │ ├── test7.cpp │ │ ├── test8.cpp │ │ ├── test9.cpp │ │ └── tostring.cpp │ ├── test1.cpp │ ├── test4.cpp │ ├── tests.h │ ├── threading │ │ ├── atomic1.cpp │ │ ├── atomic1.testing.js │ │ ├── atomic2.cpp │ │ ├── atomic2.testing.js │ │ ├── atomic3.cpp │ │ ├── atomic3.testing.js │ │ ├── atomic4.cpp │ │ ├── atomic4.testing.js │ │ ├── atomic_lowering1.cpp │ │ ├── atomic_lowering2.cpp │ │ ├── atomic_lowering3.cpp │ │ ├── thread_setup.cpp │ │ └── thread_setup.testing.js │ ├── types │ │ ├── cinheritance.cpp │ │ ├── funccasts.cpp │ │ ├── memberfunctions.cpp │ │ ├── memberfunctions2.cpp │ │ ├── packed.cpp │ │ ├── padding1.cpp │ │ ├── padding2.cpp │ │ ├── padding3.cpp │ │ ├── padding4.cpp │ │ ├── padding5.cpp │ │ ├── padding6.cpp │ │ ├── test1.cpp │ │ ├── test10.cpp │ │ ├── test11.cpp │ │ ├── test12.cpp │ │ ├── test13.cpp │ │ ├── test14.cpp │ │ ├── test16.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ ├── test5.cpp │ │ ├── test6.cpp │ │ ├── test7.cpp │ │ ├── test8.cpp │ │ ├── test9.cpp │ │ └── union64.cpp │ ├── vbases │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ └── test5.cpp │ └── virtual │ │ ├── constructor.cpp │ │ ├── interop.cpp │ │ ├── rtti.cpp │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ └── test3.cpp ├── webgl │ ├── Makefile │ ├── webgl.cpp │ └── webgl.html └── webworker-polyfill.js └── tools ├── Cheerp.cmake ├── CheerpCommon.cmake.in ├── CheerpToolchain.cmake ├── CheerpWasiToolchain.cmake └── CheerpWasmToolchain.cmake /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.6) 2 | project (Cheerp_Utils LANGUAGES) 3 | 4 | set (CHEERP_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE FILEPATH "set cheerp installation prefix") 5 | execute_process(COMMAND "${CMAKE_INSTALL_PREFIX}/bin/clang" --version 6 | OUTPUT_VARIABLE CMAKE_CHEERP_RAW_VERSION) 7 | message(WARNING "Cheerp raw version string ${CMAKE_CHEERP_RAW_VERSION}") 8 | string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" 9 | CHEERP_VERSION 10 | "${CMAKE_CHEERP_RAW_VERSION}") 11 | message(WARNING "Cheerp version match ${CHEERP_VERSION}") 12 | 13 | # scripts 14 | configure_file ( 15 | "scripts/cheerpwrap.in" 16 | "${PROJECT_BINARY_DIR}/cheerpwrap" 17 | ) 18 | 19 | install (PROGRAMS "${PROJECT_BINARY_DIR}/cheerpwrap" 20 | DESTINATION bin) 21 | install (PROGRAMS 22 | scripts/cheerp-unknown-none-g++ 23 | scripts/cheerp-unknown-none-gcc 24 | scripts/wasm32-unknown-none-g++ 25 | scripts/wasm32-unknown-none-gcc 26 | scripts/wasm32-unknown-wasi-g++ 27 | scripts/wasm32-unknown-wasi-gcc 28 | DESTINATION libexec ) 29 | 30 | # tools 31 | SET(toolchain_files_templates 32 | "tools/CheerpCommon.cmake.in" 33 | ) 34 | foreach(toolchain_file ${toolchain_files_templates}) 35 | get_filename_component(base ${toolchain_file} NAME_WE) 36 | configure_file ( 37 | ${toolchain_file} 38 | "${PROJECT_BINARY_DIR}/${base}.cmake" 39 | @ONLY 40 | ) 41 | install (FILES "${PROJECT_BINARY_DIR}/${base}.cmake" 42 | DESTINATION share/cmake/Modules/) 43 | endforeach() 44 | install (FILES 45 | "tools/CheerpToolchain.cmake" 46 | "tools/CheerpWasmToolchain.cmake" 47 | "tools/CheerpWasiToolchain.cmake" 48 | DESTINATION share/cmake/Modules/) 49 | install (FILES 50 | "tools/Cheerp.cmake" 51 | DESTINATION share/cmake/Modules/Platform) 52 | 53 | # tests 54 | install (FILES tests/dom/dom1.cpp tests/dom/test1.html 55 | DESTINATION share/cheerp/examples/dom ) 56 | 57 | install (FILES tests/webgl/webgl.cpp tests/webgl/webgl.html 58 | DESTINATION share/cheerp/examples/webgl ) 59 | 60 | # include 61 | install (DIRECTORY include/client/ 62 | DESTINATION include/client/cheerp ) 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Cheerp: A C++ compiler for the Web 2 | ================================== 3 | 4 | Please report bugs on GitHub: 5 | https://github.com/leaningtech/cheerp-meta/issues 6 | 7 | Cheerp Utilities installation 8 | --------------------------- 9 | 10 | ``` 11 | cd $CHEERP_SRC/cheerp-utils 12 | mkdir build 13 | cd build 14 | cmake -DCMAKE_INSTALL_PREFIX=/opt/cheerp .. 15 | make install 16 | ``` 17 | -------------------------------------------------------------------------------- /include/client/client.h: -------------------------------------------------------------------------------- 1 | #ifdef USE_OLD_CLIENTLIB 2 | #include "old/client.h" 3 | #else 4 | #include "new/client.h" 5 | #endif 6 | -------------------------------------------------------------------------------- /include/client/clientlib.h: -------------------------------------------------------------------------------- 1 | #ifdef USE_OLD_CLIENTLIB 2 | #include "old/clientlib.h" 3 | #else 4 | #include "new/clientlib.h" 5 | #endif 6 | -------------------------------------------------------------------------------- /include/client/coroutine.h: -------------------------------------------------------------------------------- 1 | #include "new/coroutine.h" 2 | -------------------------------------------------------------------------------- /include/client/function.h: -------------------------------------------------------------------------------- 1 | #include "new/function.h" 2 | -------------------------------------------------------------------------------- /include/client/jsexception.h: -------------------------------------------------------------------------------- 1 | #ifdef USE_OLD_CLIENTLIB 2 | #include "old/jsexception.h" 3 | #else 4 | #include "new/jsexception.h" 5 | #endif 6 | -------------------------------------------------------------------------------- /include/client/jshelper.h: -------------------------------------------------------------------------------- 1 | #include "new/jshelper.h" 2 | -------------------------------------------------------------------------------- /include/client/jsobject.h: -------------------------------------------------------------------------------- 1 | #ifdef USE_OLD_CLIENTLIB 2 | #include "old/jsobject.h" 3 | #else 4 | #include "new/jsobject.h" 5 | #endif 6 | -------------------------------------------------------------------------------- /include/client/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef USE_OLD_CLIENTLIB 2 | #include "old/memory.h" 3 | #else 4 | #include "new/memory.h" 5 | #endif 6 | -------------------------------------------------------------------------------- /include/client/new/coroutine.h: -------------------------------------------------------------------------------- 1 | #ifndef CHEERP_ASYNC_H 2 | #define CHEERP_ASYNC_H 3 | 4 | #include "cheerp/client.h" 5 | #include "cheerp/clientlib.h" 6 | 7 | #include 8 | #include 9 | 10 | template 11 | struct std::coroutine_traits*, Args...> { 12 | struct [[cheerp::genericjs]] promise_type { 13 | client::Promise* get_return_object() { 14 | return client::Promise::template _New([this](client::Function* resolve) { 15 | this->resolve = resolve; 16 | }); 17 | } 18 | 19 | auto initial_suspend() const noexcept { 20 | return std::suspend_never(); 21 | } 22 | 23 | auto final_suspend() const noexcept { 24 | return std::suspend_never(); 25 | } 26 | 27 | void return_value(T value) { 28 | resolve->call(nullptr, value); 29 | } 30 | 31 | void unhandled_exception() { 32 | // TODO 33 | } 34 | 35 | private: 36 | client::Function* resolve; 37 | }; 38 | }; 39 | 40 | template 41 | [[cheerp::genericjs]] 42 | auto operator co_await(client::Promise& promise) { 43 | struct promise_awaiter { 44 | promise_awaiter(client::Promise* promise) { 45 | this->promise = promise; 46 | } 47 | 48 | bool await_ready() const noexcept { 49 | return false; 50 | } 51 | 52 | void await_suspend(std::coroutine_handle<> handle) { 53 | promise->template then([this, handle](T value) { 54 | this->value = value; 55 | handle.resume(); 56 | }); 57 | } 58 | 59 | T await_resume() const { 60 | return value; 61 | } 62 | 63 | private: 64 | client::Promise* promise; 65 | T value; 66 | }; 67 | 68 | return promise_awaiter(&promise); 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /include/client/new/function.h: -------------------------------------------------------------------------------- 1 | #ifndef CHEERP_FUNCTION_H 2 | #define CHEERP_FUNCTION_H 3 | #include "cheerp/types.h" 4 | namespace [[cheerp::genericjs]] client { 5 | class EventListener; 6 | } 7 | namespace [[cheerp::genericjs]] cheerp { 8 | template 9 | struct FunctionTypeImpl; 10 | template 11 | struct FunctionTypeImpl { 12 | using type = R(Args...); 13 | }; 14 | template 15 | struct FunctionTypeImpl { 16 | using type = R(Args...); 17 | }; 18 | template 19 | using FunctionType = typename FunctionTypeImpl::operator())>::type; 20 | template 21 | client::EventListener* Callback(T&& func); 22 | template 23 | client::EventListener* Callback(R(*func)(Args...)); 24 | } 25 | namespace [[cheerp::genericjs]] client { 26 | template 27 | class _Function : public Function { 28 | public: 29 | template>, _Function>>> 30 | _Function(T&& func) : Function(cheerp::Callback(func)) { 31 | } 32 | template, _Function>>> 33 | _Function(R(*func)(Args...)) : Function(cheerp::Callback(func)) { 34 | } 35 | [[gnu::always_inline]] 36 | _Function(const EventListener* listener) : Function(listener) { 37 | } 38 | }; 39 | } 40 | #endif 41 | -------------------------------------------------------------------------------- /include/client/new/jsexception.h: -------------------------------------------------------------------------------- 1 | //===-- jsexception.h - C++ Wrapper for JS exceptions --------------===// 2 | // 3 | // Cheerp: The C++ compiler for the Web 4 | // 5 | // This file is distributed under the Apache License v2.0 with LLVM Exceptions. 6 | // See LICENSE.TXT for details. 7 | // 8 | // Copyright 2011-2023 Leaning Technologies 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | #ifndef _CHEERP_JSEXCEPTION 13 | #define _CHEERP_JSEXCEPTION 14 | 15 | #include "cheerp/jsobject.h" 16 | 17 | #ifdef __cplusplus 18 | 19 | namespace [[cheerp::genericjs]] cheerp 20 | { 21 | 22 | class JSException { 23 | client::Object* inner; 24 | public: 25 | JSException(client::Object* e): inner(e) 26 | { 27 | } 28 | client::Object* get() 29 | { 30 | return inner; 31 | } 32 | }; 33 | 34 | 35 | } //End of namespace cheerp 36 | 37 | #endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /include/client/new/memory.h: -------------------------------------------------------------------------------- 1 | //===-- memory.h - Type safe implementation of memcmp --------------===// 2 | // 3 | // Cheerp: The C++ compiler for the Web 4 | // 5 | // This file is distributed under the Apache License v2.0 with LLVM Exceptions. 6 | // See LICENSE.TXT for details. 7 | // 8 | // Copyright 2011-2023 Leaning Technologies 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | #ifndef _CHEERP_MEMORY_H_2a82c4dc 13 | #define _CHEERP_MEMORY_H_2a82c4dc 14 | 15 | #define CHEERP_MEMCMP(s1, s2, n) \ 16 | ({ \ 17 | /* Type safety check, types should be the same */ \ 18 | int ret = 0; \ 19 | typeof(s1) tmp1 = s1; \ 20 | typeof(s1) tmp2 = s2; \ 21 | for (size_t i=0;i 37 | inline int memcmp(const T* s1, const T* s2, size_t n) 38 | { 39 | if (n == 0) 40 | return 0; 41 | for (size_t i=0; i 17 | #endif 18 | 19 | namespace [[cheerp::genericjs]] client 20 | { 21 | 22 | class String; 23 | class Array; 24 | 25 | class [[cheerp::client_layout]] Object 26 | { 27 | private: 28 | // Make it impossible to blindly copy a browser object 29 | Object(const Object&) = delete; 30 | public: 31 | Object(); 32 | // valueOf may return different types, the users should specify which one is expected 33 | template 34 | T valueOf(); 35 | explicit operator double() const 36 | { 37 | return const_cast(this)->valueOf(); 38 | } 39 | explicit operator int() const 40 | { 41 | return const_cast(this)->valueOf(); 42 | } 43 | Object* operator[](const client::String& name) const; 44 | // operator[] for arbitrary assignment can't be expressed as we can't have a pointer to an arbitrary member of an object 45 | // We provide the following function instead 46 | void set_(const client::String& name, Object* v); 47 | #ifndef LEAN_CXX_LIB 48 | template::value, T>::type> 49 | void set_(const client::String& name, T v); 50 | #endif 51 | bool hasOwnProperty(const client::String& name); 52 | static Array* keys(Object*) [[cheerp::static]]; 53 | static Array* values(Object*) [[cheerp::static]]; 54 | }; 55 | 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/client/old/memory.h: -------------------------------------------------------------------------------- 1 | //===-- memory.h - Type safe implementation of memcmp --------------===// 2 | // 3 | // Cheerp: The C++ compiler for the Web 4 | // 5 | // This file is distributed under the Apache License v2.0 with LLVM Exceptions. 6 | // See LICENSE.TXT for details. 7 | // 8 | // Copyright 2011-2023 Leaning Technologies 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | #ifndef _CHEERP_MEMORY_H_2a82c4dc 13 | #define _CHEERP_MEMORY_H_2a82c4dc 14 | 15 | #define CHEERP_MEMCMP(s1, s2, n) \ 16 | ({ \ 17 | /* Type safety check, types should be the same */ \ 18 | int ret = 0; \ 19 | typeof(s1) tmp1 = s1; \ 20 | typeof(s1) tmp2 = s2; \ 21 | for (size_t i=0;i 37 | inline int memcmp(const T* s1, const T* s2, size_t n) 38 | { 39 | if (n == 0) 40 | return 0; 41 | for (size_t i=0; i=14.17" 33 | } 34 | }, 35 | "node_modules/undici-types": { 36 | "version": "5.26.5", 37 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 38 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 39 | "dev": true 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/check_dts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "build/index.js", 3 | "dependencies": { 4 | "typescript": "^5.3.2" 5 | }, 6 | "devDependencies": { 7 | "@types/node": "^20.10.0" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/check_dts/src/index.ts: -------------------------------------------------------------------------------- 1 | import ts from "typescript"; 2 | 3 | const program = ts.createProgram([process.argv[2]], { 4 | target: ts.ScriptTarget.ES2015, 5 | module: ts.ModuleKind.CommonJS, 6 | esModuleInterop: true, 7 | skipLibCheck: false, 8 | strict: true, 9 | }); 10 | 11 | const diagnostics = ts.getPreEmitDiagnostics(program); 12 | 13 | console.log(diagnostics.length); 14 | -------------------------------------------------------------------------------- /tests/dom/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.make 2 | 3 | all: dom1.js dom2.js 4 | -------------------------------------------------------------------------------- /tests/dom/dom1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace client; 5 | 6 | void loadCallback() 7 | { 8 | HTMLElement* body=document.get_body(); 9 | HTMLElement* newTitle=document.createElement("h1"); 10 | newTitle->set_textContent("Hello World"); 11 | body->appendChild(newTitle); 12 | } 13 | 14 | void webMain() 15 | { 16 | document.addEventListener("DOMContentLoaded",cheerp::Callback(loadCallback)); 17 | } 18 | -------------------------------------------------------------------------------- /tests/dom/dom2.cpp: -------------------------------------------------------------------------------- 1 | #include //Misc client side stuff 2 | #include //Complete DOM/HTML5 interface 3 | #include 4 | 5 | using namespace client; 6 | 7 | void setupInputAndDisplay() 8 | { 9 | client::HTMLElement * body = document.get_body(); 10 | 11 | std::string original_text = "hello, world!"; 12 | 13 | HTMLElement * textDisplay = document.createElement("h1"); 14 | textDisplay->set_textContent(original_text.c_str()); 15 | 16 | HTMLInputElement * inputBox = static_cast(document.createElement("input") ); 17 | inputBox->setAttribute("type", "text"); 18 | inputBox->setAttribute("style", "width:200px"); 19 | 20 | // This sets the default value 21 | inputBox->setAttribute("value", original_text.c_str() ); 22 | 23 | inputBox->addEventListener("input", cheerp::Callback([textDisplay, inputBox]() -> void { 24 | String * text = inputBox->get_value(); 25 | textDisplay->set_textContent( text ); 26 | 27 | }) ); 28 | 29 | body->appendChild( textDisplay ); 30 | body->appendChild( inputBox ); 31 | 32 | } 33 | 34 | void webMain() 35 | { 36 | document.addEventListener("DOMContentLoaded",cheerp::Callback(setupInputAndDisplay)); 37 | } 38 | -------------------------------------------------------------------------------- /tests/dom/test1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/dom/test2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/emscripten_tests/Makefile: -------------------------------------------------------------------------------- 1 | EMCC=~/Sources/emscripten/emcc 2 | CLOSURE=../../closure/compiler.jar 3 | 4 | all: primes memops copy corrections fannkuch fasta 5 | 6 | .PHONY: primes memops copy corrections fannkuch fasta 7 | 8 | primes: primes-cheerp.js primes-emscripten.js primes-asm.js primes-native 9 | 10 | memops: memops-cheerp.js memops-emscripten.js memops-asm.js memops-native 11 | 12 | copy: copy-cheerp.js copy-emscripten.js copy-asm.js copy-native 13 | 14 | corrections: corrections-cheerp.js corrections-emscripten.js corrections-asm.js corrections-native 15 | 16 | fannkuch: fannkuch-emscripten.js fannkuch-cheerp.js fannkuch-asm.js fannkuch-native 17 | 18 | fasta: fasta-emscripten.js fasta-cheerp.js fasta-asm.js fasta-native 19 | 20 | %-native: %.cpp 21 | clang++ -fno-math-errno -O2 $^ -o $@ 22 | 23 | %-emscripten.js: %.cpp 24 | ${EMCC} -O2 $^ -o $@ 25 | 26 | %-asm.js: %.cpp 27 | ${EMCC} -s ASM_JS=1 -O2 $^ -o $@ 28 | 29 | %-cheerp.js: %.js 30 | sed -i -e "s/__Z7webMainv();/_main();/g" -e "s/_sqrt/Math.sqrt/g" -e "s/_printf/print/g" -e "s/_puts(/print(/g" $^ 31 | java -jar ${CLOSURE} $^ > $@ 32 | 33 | clean: 34 | rm -fv primes-cheerp.js primes-emscripten.js primes-asm.js primes-native memops-cheerp.js memops-emscripten.js memops-asm.js memops-native copy-cheerp.js copy-emscripten.js copy-asm.js copy-native corrections-cheerp.js corrections-emscripten.js corrections-asm.js corrections-native fannkuch-emscripten.js fannkuch-cheerp.js fannkuch-asm.js fannkuch-native fasta-emscripten.js fasta-cheerp.js fasta-asm.js fasta-native 35 | -------------------------------------------------------------------------------- /tests/emscripten_tests/benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | V8=../../v8/out/native/d8 4 | SM=$HOME/Sources/mozilla-central-afb7995ef276/js/src/js 5 | TEST=$1 6 | 7 | rm -f benchmark-data-${TEST}-* 8 | 9 | echo Benchmarking $TEST-Cheerp on V8 10 | count=0; 11 | while [ $count -lt 10 ] 12 | do 13 | time -f "%e" -a -o benchmark-data-${TEST}-cheerp-v8 $V8 $TEST-cheerp.js 14 | count=$(($count+1)) 15 | done 16 | 17 | echo Benchmarking $TEST-Emscripten on V8 18 | count=0; 19 | while [ $count -lt 10 ] 20 | do 21 | time -f "%e" -a -o benchmark-data-${TEST}-emscripten-v8 $V8 $TEST-emscripten.js 22 | count=$(($count+1)) 23 | done 24 | 25 | echo Benchmarking $TEST-Cheerp on SpiderMonkey 26 | count=0; 27 | while [ $count -lt 10 ] 28 | do 29 | time -f "%e" -a -o benchmark-data-${TEST}-cheerp-spidermonkey $SM --no-baseline --no-ion $TEST-cheerp.js 30 | count=$(($count+1)) 31 | done 32 | 33 | echo Benchmarking $TEST-Emscripten on SpiderMonkey 34 | count=0; 35 | while [ $count -lt 10 ] 36 | do 37 | time -f "%e" -a -o benchmark-data-${TEST}-emscripten-spidermonkey $SM --no-baseline --no-ion $TEST-emscripten.js 38 | count=$(($count+1)) 39 | done 40 | 41 | echo Benchmarking $TEST-Asm.js on SpiderMonkey 42 | count=0; 43 | while [ $count -lt 10 ] 44 | do 45 | time -f "%e" -a -o benchmark-data-${TEST}-asm.js-spidermonkey $SM --no-baseline --no-ion $TEST-asm.js 46 | count=$(($count+1)) 47 | done 48 | 49 | echo Benchmarking $TEST-Native 50 | count=0; 51 | while [ $count -lt 10 ] 52 | do 53 | time -f "%e" -a -o benchmark-data-${TEST}-native ./${TEST}-native 54 | count=$(($count+1)) 55 | done 56 | 57 | 58 | -------------------------------------------------------------------------------- /tests/emscripten_tests/copy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | struct vec { 3 | int x, y, z; 4 | int r, g, b; 5 | vec(int x_, int y_, int z_, int r_, int g_, int b_) : x(x_), y(y_), z(z_), r(r_), g(g_), b(b_) {} 6 | static vec add(vec a, vec b) { 7 | return vec(a.x+b.x, a.y+b.y, a.z+b.z, a.r+b.r, a.g+b.g, a.b+b.b); 8 | } 9 | void norm() { 10 | x %= 1024; 11 | y %= 1024; 12 | z %= 1024; 13 | r %= 1024; 14 | b %= 1024; 15 | g %= 1024; 16 | } 17 | int sum() { return x + y + z + r + g + b; } 18 | }; 19 | int main() { 20 | int total = 0; 21 | for (int i = 0; i < 12500; i++) { 22 | for (int j = 0; j < 1000; j++) { 23 | vec c(i, i+i%10, j*2, i%255, j%120, i%15); 24 | vec d(j+i%10, j*2, j%255, i%120, j%15, j); 25 | vec e = c; 26 | c.norm(); 27 | d.norm(); 28 | vec f = vec::add(c, d); 29 | f = vec::add(e, f); 30 | f.norm(); 31 | f = vec::add(d, f); 32 | total += f.sum() % 100; 33 | total += c.sum() + d.sum() + e.sum(); 34 | total %= 10240; 35 | } 36 | } 37 | printf("sum:%d\n", total); 38 | return 1; 39 | } 40 | -------------------------------------------------------------------------------- /tests/emscripten_tests/corrections.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | int N = 4100; 5 | int M = 4100; 6 | unsigned int f = 0; 7 | unsigned short s = 0; 8 | for (int t = 0; t < M; t++) { 9 | for (int i = 0; i < N; i++) { 10 | f += i / ((t % 5)+1); 11 | if (f > 1000) f /= (t % 3)+1; 12 | if (i % 4 == 0) f += sqrt(i) * (i % 8 == 0 ? 1 : -1); 13 | s += (short(f)*short(f)) % 256; 14 | } 15 | } 16 | printf("final: %d:%d.\n", f, s); 17 | return 1; 18 | } 19 | -------------------------------------------------------------------------------- /tests/emscripten_tests/memops.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | int main() { 5 | int N = 1024*1024; 6 | int M = 800; 7 | int final = 0; 8 | char *buf = (char*)malloc(N); 9 | for (int t = 0; t < M; t++) { 10 | for (int i = 0; i < N; i++) 11 | buf[i] = (i + final)%256; 12 | for (int i = 0; i < N; i++) 13 | final += buf[i] & 1; 14 | final = final % 1000; 15 | } 16 | printf("final: %d.\\n", final); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /tests/emscripten_tests/primes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | int primes = 0, curri = 2; 5 | while (primes < 220000) { 6 | int ok = true; 7 | for (int j = 2; j < sqrt(curri); j++) { 8 | if (curri % j == 0) { 9 | ok = false; 10 | break; 11 | } 12 | } 13 | if (ok) { 14 | primes++; 15 | } 16 | curri++; 17 | } 18 | printf("lastprime: %d.\\n", curri-1); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /tests/frontend/ffi/func_arg_func.cpp: -------------------------------------------------------------------------------- 1 | // first call should be ok, second error 2 | int foo(int(*bar)()) { 3 | return bar(); 4 | } 5 | int bar() { 6 | return 10; 7 | } 8 | 9 | [[cheerp::genericjs]] 10 | int main() { 11 | 12 | foo(bar); 13 | foo(&bar); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tests/frontend/ffi/func_arg_str.cpp: -------------------------------------------------------------------------------- 1 | // first call should be ok, second error 2 | int foo(const char* c) { 3 | return c[0]; 4 | } 5 | [[cheerp::genericjs]] 6 | int main() { 7 | foo("test"); 8 | const char* a = "test"; 9 | foo(a); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tests/frontend/ffi/func_arg_variadic.cpp: -------------------------------------------------------------------------------- 1 | // first call is ok, second error 2 | 3 | int foo(int i, ...) { 4 | return i; 5 | } 6 | 7 | [[cheerp::genericjs]] 8 | int main() { 9 | foo(1,1); 10 | foo(1,1LL); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /tests/frontend/ffi/func_args.cpp: -------------------------------------------------------------------------------- 1 | // All calls should emit an error 2 | 3 | int foo(long long a) { 4 | return a+1; 5 | } 6 | struct Foo { 7 | Foo(long long a) { 8 | } 9 | int foo(long long a) { 10 | return ::foo(a); 11 | } 12 | int operator()(long long a) { 13 | return foo(a); 14 | } 15 | int operator[](long long a) { 16 | return foo(a); 17 | } 18 | static int foos(long long a) { 19 | return ::foo(a); 20 | } 21 | }; 22 | [[cheerp::genericjs]] 23 | int main() { 24 | long long a = 1LL<<33; 25 | Foo f(a); 26 | foo(a); 27 | f.foo(a); 28 | f(a); 29 | f[a]; 30 | Foo::foos(a); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /tests/import-polyfills.js: -------------------------------------------------------------------------------- 1 | globalThis.Blob = require('node:buffer').Blob; 2 | globalThis.Worker = require('../../webworker-polyfill.js').Worker; 3 | -------------------------------------------------------------------------------- /tests/tests.make: -------------------------------------------------------------------------------- 1 | CLANG=/opt/cheerp/bin/clang++ 2 | 3 | %.js: %.cpp 4 | ${CLANG} -target cheerp -O2 $^ -o $@ 5 | -------------------------------------------------------------------------------- /tests/unit/anyref/args.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2020 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | [[cheerp::genericjs]] 10 | client::String* retValJs(const char* str) 11 | { 12 | return new client::String(str); 13 | } 14 | [[cheerp::genericjs]] 15 | bool argJs(client::String* s) 16 | { 17 | return (new client::String("aaa") == s); 18 | } 19 | [[cheerp::wasm]] 20 | [[clang::optnone]] 21 | client::String* forward(client::String* s) 22 | { 23 | return s; 24 | } 25 | 26 | void webMain() 27 | { 28 | client::String* s = retValJs("aaa"); 29 | bool eq = argJs(s); 30 | assertEqual(eq, true, "anyref argument passing 1/2"); 31 | s = forward(s); 32 | eq = argJs(s); 33 | assertEqual(eq, true, "anyref argument passing 2/2"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/bitfield/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | short a1:15; 10 | short a2:2; 11 | int a3:10; 12 | }; 13 | 14 | void webMain() 15 | { 16 | A a; 17 | a.a1=7; 18 | a.a2=1; 19 | a.a3=511; 20 | assertEqual(a.a1, 7, "Bitfield test 1/3"); 21 | assertEqual(a.a2, 1, "Bitfield test 2/3"); 22 | assertEqual(a.a3, 511, "Bitfield test 2/3"); 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/bitfield/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int a1:15; 10 | int a2:16; 11 | int a3:3; 12 | }; 13 | 14 | void webMain() 15 | { 16 | A a; 17 | a.a1=-8191; 18 | a.a2=8191; 19 | a.a3=2; 20 | assertEqual(a.a1, -8191, "Bitfield test 1/3"); 21 | assertEqual(a.a2, 8191, "Bitfield test 2/3"); 22 | assertEqual(a.a3, 2, "Bitfield test 3/3"); 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/bitfield/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | short a1:15; 10 | short a2:2; 11 | }; 12 | 13 | void webMain() 14 | { 15 | A a; 16 | a.a1=7; 17 | a.a2=1; 18 | assertEqual(a.a1, 7, "Bitfield test 1/2"); 19 | assertEqual(a.a2, 1, "Bitfield test 2/2"); 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/bitfield/test4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | short a1:2; 10 | }; 11 | 12 | struct B: public A 13 | { 14 | short a2:5; 15 | }; 16 | 17 | void webMain() 18 | { 19 | B a; 20 | a.a1=1; 21 | a.a2=15; 22 | assertEqual(a.a1, 1, "Bitfield test 1/2"); 23 | assertEqual(a.a2, 15, "Bitfield test 2/2"); 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/bitfield/test5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | long long a1:63; 10 | int b; 11 | }; 12 | 13 | void webMain() 14 | { 15 | A a; 16 | a.a1=(1LL<<61)|23; 17 | a.b=0xdeadbeaf; 18 | assertEqual(a.a1, 23, "Bitfield test 1/2"); 19 | assertEqual(a.b, 0xdeadbeaf, "Bitfield test 2/2"); 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/cli/argv.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | extern char **environ; 10 | 11 | int main(int argc, char **argv) { 12 | assertEqual(argc, 1, "expected one argument"); 13 | assertEqual(argv!=nullptr, true, "expected argv to not be a nullptr"); 14 | assertEqual(strcmp(argv[0], "argv.cpp"), 0, "expected argument 0 to be the filename"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/cli/argv.testing.js: -------------------------------------------------------------------------------- 1 | var env=[]; 2 | var argv=["argv.cpp"]; 3 | 4 | function onInstantiation(_) { 5 | } 6 | -------------------------------------------------------------------------------- /tests/unit/cli/env.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | extern char **environ; 10 | 11 | int main(int argc, char **argv, char **env) { 12 | assertEqual(strcmp(getenv("TEST"), "1")==0, true, "expected TEST environment variable to be 1"); 13 | assertEqual(strcmp(env[0], "TEST=1")==0, true, "expected environ to be passed to main"); 14 | assertEqual(env[1]==nullptr, true, "expected only one environment variable"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/cli/env.testing.js: -------------------------------------------------------------------------------- 1 | var env=["TEST=1"]; 2 | var argv=[]; 3 | 4 | function onInstantiation(_) { 5 | } 6 | -------------------------------------------------------------------------------- /tests/unit/client/_delete.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace [[cheerp::genericjs]] client 4 | { 5 | class [[cheerp::client_layout]] ToBeDeleted 6 | { 7 | public: 8 | ToBeDeleted(int a); 9 | [[cheerp::interface_name(("delete"))]] void _delete(); 10 | [[cheerp::interface_name(("catch"))]] int _catch(); 11 | }; 12 | int counterAlive(); 13 | template 14 | [[cheerp::interface_name(("assert"))]] 15 | void _assert(T& someObject); 16 | } 17 | 18 | [[cheerp::genericjs]] 19 | int main() 20 | { 21 | assertEqual(client::counterAlive(), 0, "Check counter 1/3"); 22 | 23 | client::ToBeDeleted* TBD = new client::ToBeDeleted(123); 24 | client::_assert(*TBD); 25 | assertEqual(client::counterAlive(), 1, "Check counter 2/3"); 26 | assertEqual(TBD->_catch(), 123, "Call actual catch"); 27 | 28 | TBD -> _delete(); 29 | 30 | assertEqual(client::counterAlive(), 0, "Check counter 3/3"); 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/client/_delete.testing.js: -------------------------------------------------------------------------------- 1 | global.counter = 0; 2 | global.externValue = 100; 3 | global.ToBeDeleted = function(a) 4 | { 5 | this.a = a; 6 | counter++; 7 | } 8 | global.ToBeDeleted.prototype.catch=function (){ 9 | return this.a; 10 | }; 11 | global.ToBeDeleted.prototype.delete=function (){ 12 | counter--; 13 | }; 14 | global.counterAlive=function(){ 15 | return counter; 16 | }; 17 | global.assert=function(obj){ 18 | if (obj.catch() == obj.a) 19 | console.log("Assert", "SUCCESS"); 20 | else 21 | console.log("Assert", "FAILURE"); 22 | }; 23 | 24 | function onInstantiation(_) 25 | { 26 | if (counter === 0) 27 | console.log("Module export", "SUCCESS"); 28 | else 29 | console.log("Module export", "FAILURE"); 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/client/class.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | namespace [[cheerp::genericjs]] client 9 | { 10 | struct SomeClass : public Object 11 | { 12 | SomeClass(int X); 13 | static int someFunc(); 14 | int otherFunc(); 15 | }; 16 | } 17 | 18 | class [[cheerp::jsexport]][[cheerp::genericjs]] SomeClass 19 | { 20 | public: 21 | SomeClass(int Y) 22 | : counter(Y) 23 | { 24 | } 25 | static int someFunc() 26 | { 27 | return invocations; 28 | } 29 | int otherFunc() 30 | { 31 | invocations++; 32 | counter += 7; 33 | return counter; 34 | } 35 | private: 36 | int counter; 37 | static int invocations; 38 | }; 39 | 40 | int SomeClass::invocations = 0; 41 | 42 | int [[cheerp::genericjs]] main() 43 | { 44 | client::SomeClass* c = new client::SomeClass(7); 45 | 46 | assertEqual(client::SomeClass::someFunc(), 0, "Static method"); 47 | 48 | assertEqual(c->otherFunc(), 14, "Non static method"); 49 | assertEqual(c->otherFunc(), 21, "Non static method"); 50 | assertEqual(c->otherFunc(), 28, "Non static method"); 51 | 52 | assertEqual(client::SomeClass::someFunc(), 3, "Static method"); 53 | 54 | return 1; 55 | } 56 | -------------------------------------------------------------------------------- /tests/unit/client/globals.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace [[cheerp::genericjs]] client 4 | { 5 | extern int externValue; 6 | int internValue = 100; 7 | 8 | class [[cheerp::client_layout]] SomeClass 9 | { 10 | public: 11 | SomeClass(int); 12 | void doTest(int); 13 | }; 14 | extern SomeClass* externPtr; 15 | SomeClass* internPtr = new SomeClass(14); 16 | extern SomeClass externInstance; 17 | } 18 | 19 | [[cheerp::genericjs]] 20 | void someFunc(client::SomeClass& instance) 21 | { 22 | instance.doTest(33); 23 | } 24 | 25 | [[cheerp::genericjs]] 26 | int main() 27 | { 28 | assertEqual(client::internValue, 100, "Internal value 1/3"); 29 | client::internValue = 7; 30 | assertEqual(client::internValue, 7, "Internal value 2/3"); 31 | assertEqual(client::internValue * client::internValue, 49, "Internal value 3/3"); 32 | 33 | assertEqual(client::externValue, 100, "External value 1/3"); 34 | client::externValue = 7; 35 | assertEqual(client::externValue, 7, "External value 2/3"); 36 | assertEqual(client::externValue * client::externValue, 49, "External value 3/3"); 37 | 38 | client::internPtr->doTest(-42); 39 | client::externPtr->doTest(123); 40 | 41 | someFunc(client::externInstance); 42 | 43 | return 1; 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/client/globals.testing.js: -------------------------------------------------------------------------------- 1 | global.externValue = 100; 2 | global.SomeClass = function(a) 3 | { 4 | this.inner = a; 5 | } 6 | global.SomeClass.prototype.doTest=function (b){ 7 | if (this.inner*-3 === b) 8 | console.log("doTest", "SUCCESS"); 9 | else 10 | console.log("doTest", "FAILURE"); 11 | }; 12 | global.externPtr = new SomeClass(-41); 13 | global.externInstance = new SomeClass(-11); 14 | 15 | function onInstantiation(_) { 16 | if (externValue === 7) 17 | console.log("Module export", "SUCCESS"); 18 | else 19 | console.log("Module export", "FAILURE"); 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/client/nested-namespaces.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | namespace [[cheerp::genericjs]] client 8 | { 9 | void someFunc(); 10 | 11 | namespace [[cheerp::genericjs]] first 12 | { 13 | void someFunc(); 14 | 15 | namespace [[cheerp::genericjs]] second 16 | { 17 | void someFunc(); 18 | 19 | namespace [[cheerp::genericjs]] third 20 | { 21 | void someFunc(); 22 | }; 23 | }; 24 | }; 25 | } 26 | 27 | int counter = 0; 28 | 29 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 30 | { 31 | counter += 1; 32 | } 33 | 34 | namespace first 35 | { 36 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 37 | { 38 | counter += 2; 39 | } 40 | 41 | namespace second 42 | { 43 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 44 | { 45 | counter += 4; 46 | } 47 | namespace third 48 | { 49 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 50 | { 51 | counter += 8; 52 | } 53 | } 54 | } 55 | } 56 | 57 | int [[cheerp::genericjs]] main() 58 | { 59 | client::someFunc(); 60 | assertEqual(counter, 1, "Nested namespace 1/4"); 61 | 62 | client::first::someFunc(); 63 | assertEqual(counter, 3, "Nested namespace 2/4"); 64 | 65 | client::first::second::someFunc(); 66 | assertEqual(counter, 7, "Nested namespace 3/4"); 67 | 68 | client::first::second::third::someFunc(); 69 | assertEqual(counter, 15, "Nested namespace 4/4"); 70 | 71 | return 1; 72 | } 73 | -------------------------------------------------------------------------------- /tests/unit/client/setter-getter.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include "tests.h" 7 | 8 | namespace [[cheerp::genericjs]] client 9 | { 10 | namespace [[cheerp::genericjs]] someNamespace 11 | { 12 | void set_(int a, int b); 13 | int get_(int a); 14 | void set_(const String& a, int b); 15 | int get_(const String& a); 16 | 17 | void set_someString(int b); 18 | int get_someString(); 19 | } 20 | } 21 | 22 | namespace someNamespace 23 | { 24 | //Needed to force the namespace to be declared 25 | void [[cheerp::jsexport]] emptyFunc() 26 | { 27 | } 28 | } 29 | 30 | void [[cheerp::genericjs]] webMain() 31 | { 32 | // Test set_ and get_ generic versions 33 | client::someNamespace::set_(6, 36); 34 | client::someNamespace::set_(client::String("someString"), -36); 35 | assertEqual(client::someNamespace::get_(6), 36, "set_/get_ in namespace 1/2"); 36 | assertEqual(client::someNamespace::get_(client::String("someString")), -36, "set_/get_ in namespace 2/2"); 37 | 38 | // Test set_ and get_ non-generic versions 39 | assertEqual(client::someNamespace::get_someString(), -36, "get_* in namespace 1/2"); 40 | client::someNamespace::set_someString(100); 41 | assertEqual(client::someNamespace::get_someString(), 100, "get_* in namespace 2/2"); 42 | } 43 | -------------------------------------------------------------------------------- /tests/unit/client/static-methods.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | namespace [[cheerp::genericjs]] client 9 | { 10 | void someFunc(); 11 | 12 | struct first : public Object 13 | { 14 | static void someFunc(); 15 | 16 | struct second : public Object 17 | { 18 | static void someFunc(); 19 | 20 | struct third : public Object 21 | { 22 | static void someFunc(); 23 | }; 24 | }; 25 | }; 26 | } 27 | 28 | int counter = 0; 29 | 30 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 31 | { 32 | counter += 1; 33 | } 34 | 35 | namespace first 36 | { 37 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 38 | { 39 | counter += 2; 40 | } 41 | 42 | namespace second 43 | { 44 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 45 | { 46 | counter += 4; 47 | } 48 | namespace third 49 | { 50 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 51 | { 52 | counter += 8; 53 | } 54 | } 55 | } 56 | } 57 | 58 | int [[cheerp::genericjs]] main() 59 | { 60 | client::someFunc(); 61 | assertEqual(counter, 1, "Free standing function"); 62 | 63 | client::first::someFunc(); 64 | assertEqual(counter, 3, "Nested struct 1/3"); 65 | 66 | client::first::second::someFunc(); 67 | assertEqual(counter, 7, "Nested struct 2/3"); 68 | 69 | client::first::second::third::someFunc(); 70 | assertEqual(counter, 15, "Nested struct 3/3"); 71 | 72 | return 1; 73 | } 74 | -------------------------------------------------------------------------------- /tests/unit/client/typeof.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | class [[cheerp::genericjs]] [[cheerp::jsexport]] Base {}; 9 | class [[cheerp::genericjs]] [[cheerp::jsexport]] Derived : public Base {}; 10 | 11 | #define TEST(value, type) assertEqual(value->_typeof()->toUtf8(), std::string(type), "typeof " #value " == " #type) 12 | 13 | [[cheerp::genericjs]] 14 | int main() { 15 | client::_Any* base = new client::_Any(new Base()); 16 | client::_Any* derived = new client::_Any(new Derived()); 17 | client::_Any* primitiveString = new client::String("test"); 18 | client::_Any* primitiveNumber = new client::_Any(1); 19 | client::_Any* primitiveBoolean; 20 | client::Object* object = new client::Object(); 21 | client::Object* string = new client::Object(primitiveString); 22 | client::Number* number = new client::Number(); 23 | client::Boolean* boolean = new client::Boolean(); 24 | client::Function* function = new client::Function(); 25 | client::Array* array = new client::Array(); 26 | client::TArray<>* tarray = new client::TArray<>(); 27 | client::Map<>* map = new client::Map<>(); 28 | 29 | __asm__("true" : "=r"(primitiveBoolean)); 30 | 31 | TEST(base, "object"); 32 | TEST(derived, "object"); 33 | TEST(primitiveString, "string"); 34 | TEST(primitiveNumber, "number"); 35 | TEST(primitiveBoolean, "boolean"); 36 | TEST(object, "object"); 37 | TEST(string, "object"); 38 | TEST(number, "object"); 39 | TEST(boolean, "object"); 40 | TEST(function, "function"); 41 | TEST(array, "object"); 42 | TEST(tarray, "object"); 43 | TEST(map, "object"); 44 | 45 | return 1; 46 | } 47 | -------------------------------------------------------------------------------- /tests/unit/closures/test1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Test cheerpCreateClosure and cheerpCreateClosureSplit, with multiple arguments 5 | // and return values 6 | 7 | void webMain() 8 | { 9 | int c = unitBlackBox(3); 10 | int d = unitBlackBox(4); 11 | auto cb = cheerp::Callback([c,d](int a, int b) 12 | { 13 | return a+b+c+d; 14 | }); 15 | auto cbsplit = cheerp::Callback([c](int a, int b) 16 | { 17 | return a+b+c; 18 | }); 19 | assertEqual(reinterpret_cast(cb)(1,2), 10, "Basic closure creation 1/2"); 20 | assertEqual(reinterpret_cast(cbsplit)(1,2), 6, "Basic closure creation 2/2"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/closures/test2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int ConsCount = 0; 5 | static int DestCount = 0; 6 | static int CopyCount = 0; 7 | static int MoveCount = 0; 8 | struct A { 9 | int i; 10 | A(int i): i(i) { 11 | ConsCount++; 12 | } 13 | ~A(){ 14 | DestCount++; 15 | } 16 | A(const A& a): i(a.i) { 17 | CopyCount++; 18 | } 19 | A(A&& a): i(a.i) { 20 | MoveCount++; 21 | } 22 | }; 23 | 24 | int foo(int a) 25 | { 26 | return a+unitBlackBox(2*a); 27 | } 28 | void webMain() 29 | { 30 | A a(1); 31 | auto l = [a{std::move(a)}](int b) 32 | { 33 | return a.i+b; 34 | }; 35 | 36 | { 37 | auto cl = cheerp::make_closure(std::move(l)); 38 | auto cl1 = std::move(cl); 39 | assertEqual(cl1(unitBlackBox(2)), 3, "Create Closure from lambda with captures 1/1"); 40 | } 41 | assertEqual(ConsCount, 1, "Lambda object lifecycle 1/4"); 42 | assertEqual(DestCount, 1, "Lambda object lifecycle 2/4"); 43 | assertEqual(CopyCount, 0, "Lambda object lifecycle 3/4"); 44 | assertEqual(MoveCount, 2, "Lambda object lifecycle 4/4"); 45 | 46 | 47 | auto cl2 = cheerp::make_closure([](int a) 48 | { 49 | return a+unitBlackBox(a); 50 | }); 51 | assertEqual(cl2(unitBlackBox(2)), 4, "Create Closure from lambda without captures 1/1"); 52 | 53 | cl2 = cheerp::Closure(&foo); 54 | assertEqual(cl2(unitBlackBox(2)), 6, "Create Closure from function pointer 1/1"); 55 | } 56 | -------------------------------------------------------------------------------- /tests/unit/closures/test3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int ConsCount = 0; 5 | static int DestCount = 0; 6 | static int CopyCount = 0; 7 | static int MoveCount = 0; 8 | struct A { 9 | int i; 10 | A(int i): i(i) { 11 | ConsCount++; 12 | } 13 | ~A(){ 14 | DestCount++; 15 | } 16 | A(const A& a): i(a.i) { 17 | CopyCount++; 18 | } 19 | A(A&& a): i(a.i) { 20 | MoveCount++; 21 | } 22 | }; 23 | 24 | int foo(int a) 25 | { 26 | return a+unitBlackBox(2*a); 27 | } 28 | int eventEmitter(client::EventListener* e) 29 | { 30 | int res = reinterpret_cast(e)(unitBlackBox(1)); 31 | return res; 32 | } 33 | void webMain() 34 | { 35 | A a(1); 36 | auto l = [a{std::move(a)}](int b) 37 | { 38 | return a.i+b; 39 | }; 40 | 41 | client::EventListener* el = nullptr; 42 | { 43 | auto cb = cheerp::make_closure(std::move(l)); 44 | el = cb; 45 | assertEqual(eventEmitter(el), 2, "Calling closures through EventListener 1/1"); 46 | } 47 | assertEqual(DestCount, 0, "Escaping closure lifecycle 1/2"); 48 | cheerp::freeCallback(el); 49 | assertEqual(DestCount, 1, "Escaping closure lifecycle 2/2"); 50 | } 51 | -------------------------------------------------------------------------------- /tests/unit/closures/test4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static int ConsCount = 0; 6 | static int DestCount = 0; 7 | static int CopyCount = 0; 8 | static int MoveCount = 0; 9 | struct A { 10 | int i; 11 | A(int i): i(i) { 12 | ConsCount++; 13 | } 14 | ~A(){ 15 | DestCount++; 16 | } 17 | A(const A& a): i(a.i) { 18 | CopyCount++; 19 | } 20 | A(A&& a): i(a.i) { 21 | MoveCount++; 22 | } 23 | int operator()(int b) 24 | { 25 | return i+b; 26 | } 27 | }; 28 | 29 | [[cheerp::genericjs]] 30 | int eventEmitter(client::EventListener* e) 31 | { 32 | int res = reinterpret_cast(e)(unitBlackBox(1)); 33 | return res; 34 | } 35 | [[cheerp::genericjs]] 36 | void webMain() 37 | { 38 | A a(1); 39 | client::EventListener* el = nullptr; 40 | { 41 | el = cheerp::Callback(a); 42 | assertEqual(eventEmitter(el), 2, "Calling functor through EventListener 1/1"); 43 | el = cheerp::Callback(std::function(std::move(a))); 44 | assertEqual(eventEmitter(el), 2, "Calling std::function through EventListener 1/1"); 45 | } 46 | assertEqual(DestCount, 1, "Escaping std::function lifecycle 1/2"); 47 | cheerp::freeCallback(el); 48 | assertEqual(DestCount, 2, "Escaping std::function lifecycle 2/2"); 49 | } 50 | -------------------------------------------------------------------------------- /tests/unit/codegen/64bitenum.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | enum class BIG_ENUM : uint64_t 8 | { 9 | SMALL_VALUE = 1, 10 | BIG_VALUE = 0xffff00000000 11 | }; 12 | 13 | void webMain() 14 | { 15 | BIG_ENUM a = BIG_ENUM::SMALL_VALUE; 16 | assertEqual(1, (int)a, "64-bit wide enum 1/3"); 17 | assertEqual(BIG_ENUM(1), BIG_ENUM::SMALL_VALUE, "64-bit wide enum 2/3"); 18 | volatile BIG_ENUM b = BIG_ENUM::BIG_VALUE; 19 | assertEqual(a < b, true, "64-bit wide enum 3/3"); 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/codegen/64bitpointerarith.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | const char* buf = "abcdefghi"; 10 | const char* volatile a = buf+5; 11 | volatile long long off = 2; 12 | const char* volatile b = a + off; 13 | const char* volatile c = a - off; 14 | assertEqual(*a, 'f', "64-bit wide pointer offsets 1/3"); 15 | assertEqual(*b, 'h', "64-bit wide pointer offsets 2/3"); 16 | assertEqual(*c, 'd', "64-bit wide pointer offsets 3/3"); 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/codegen/64bitrewrite.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2020 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct Foo { 8 | int i; 9 | long long j; 10 | }; 11 | 12 | int i = 1; 13 | Foo fg{1,(long long)&i+0x0f00000000000001-(long long)&i}; 14 | 15 | void webMain() 16 | { 17 | assertEqual(fg.j, 0x0f00000000000001, "Rewriting i64 in types and expressions 1/2"); 18 | assertEqual((long long)&fg + 0x0f00000000000001 - (long long)&fg, 0x0f00000000000001, "Rewriting i64 in types and expressions 2/2"); 19 | } 20 | -------------------------------------------------------------------------------- /tests/unit/codegen/abs.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | template 9 | int computeFunc(int A) 10 | { 11 | T B = A; 12 | B *= A; 13 | B *= A; 14 | B = std::abs(B); 15 | return B % T(123123); 16 | } 17 | 18 | int main() 19 | { 20 | int X = 0; 21 | for (int i=-100; i<100; i++) 22 | X += computeFunc(i) + computeFunc(i << 5) + computeFunc(i * 1e5 + 12); 23 | assertEqual(X, 32038773, "Absolute value summation 1/3"); 24 | 25 | int Y = 0; 26 | for (int i=-100; i<100; i++) 27 | Y += computeFunc(i) + computeFunc(i << 5) + computeFunc(i * 1e5 + 12); 28 | assertEqual(Y, 33131675, "Absolute value summation 2/3"); 29 | 30 | int Z = 0; 31 | for (int i=-100; i<100; i++) 32 | Z += computeFunc(i) + computeFunc(i << 5) + computeFunc(i * 1e5 + 12); 33 | assertEqual(Z, 3542, "Absolute value summation 3/3"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/codegen/advancedasm.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | namespace client { 9 | 10 | class IntString: public Object { 11 | public: 12 | int get_field1(); 13 | client::String* get_field2(); 14 | }; 15 | 16 | } 17 | 18 | void webMain() 19 | { 20 | int a; 21 | client::String* s = new client::String("testString"); 22 | __asm__("1+%1.length" : "=r"(a) : "r"(s)); 23 | assertEqual(a, 11, "Advanced inline asm 1/3"); 24 | double b; 25 | __asm__("0.5+%1.length" : "=r"(b) : "r"(s)); 26 | assertEqual(b, 10.5, "Advanced inline asm 2/3"); 27 | client::String* s2; 28 | __asm__("%1" : "=r"(s2) : "r"(s)); 29 | assertEqual(s2, s, "Advanced inline asm 3/3"); 30 | // Test clobbering 31 | __asm__("var f=%0" : : "r"(3) : "f","g"); 32 | 33 | // Test CHEERP_OBJECT macro 34 | int field1 = 1; 35 | client::String* field2 = new client::String("hello"); 36 | client::IntString* is = static_cast(CHEERP_OBJECT(field1, field2)); 37 | assertEqual(is->get_field1(), field1, "CHEERP_OBJECT macro 1/2"); 38 | assertEqual(is->get_field2(), field2, "CHEERP_OBJECT macro 2/2"); 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/codegen/bswap.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | uint16_t a = 0x11AA; 8 | 9 | void webMain() 10 | { 11 | //Test that bswaps are properly handled 12 | volatile uint16_t b = __builtin_bswap16(a); 13 | 14 | uint16_t b2 = b; 15 | assertEqual(a, (uint16_t)0x11AA, "bswap support 1/2"); 16 | assertEqual(b2, (uint16_t)0xAA11, "bswap support 2/2"); 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/codegen/byval.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | constexpr int SIZE = 10; 4 | struct Foo { 5 | int a[SIZE]{0}; 6 | int b{0}; 7 | [[clang::optnone]] 8 | void stuff(int i) { 9 | a[0] = i; 10 | for (int i = 1; i < SIZE; i++) 11 | { 12 | a[i] = a[i-1] + i; 13 | } 14 | } 15 | }; 16 | 17 | [[clang::optnone]] void test(Foo f) { 18 | f.stuff(666); 19 | } 20 | void webMain() { 21 | Foo f; 22 | int a = unitBlackBox(10); 23 | f.stuff(a); 24 | assertEqual(f.a[0], a, "ByVal support 1/2"); 25 | test(f); 26 | assertEqual(f.a[0], a, "ByVal support 2/2"); 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/codegen/covariant-pa.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int val = 42; 10 | virtual A* covariantFunc() 11 | { 12 | return this; 13 | } 14 | }; 15 | 16 | struct B: public A 17 | { 18 | B* covariantFunc() override 19 | { 20 | return this; 21 | } 22 | }; 23 | 24 | void webMain() 25 | { 26 | struct A* volatile a = new B; 27 | A* ret1 = a->covariantFunc(); 28 | // Force REGULAR representation for returned A* 29 | volatile intptr_t forceRegular = reinterpret_cast(ret1); 30 | assertEqual(ret1->val, 42, "PointerAnalyzer safety for covariant returns"); 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/codegen/dynalloca.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | //Test dynamically sized allocas 10 | volatile int size = 10; 11 | int sum = 0; 12 | if (size > 4) 13 | { 14 | int arr[size]; 15 | for (int i = 0; i < size; i++) 16 | { 17 | arr[i] = i; 18 | } 19 | for (int i = 0; i < size; i++) 20 | { 21 | sum += arr[i]; 22 | } 23 | } 24 | 25 | assertEqual(sum, 45, "Dynamic alloca support 1/1"); 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/codegen/dynstack.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2019 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | // Test dynamic stack allocation 10 | volatile int length = 100; 11 | double v1[length]; 12 | for(int i=0;i(alloca(length*sizeof(double))); 17 | for(int i=0;i 6 | 7 | void webMain() 8 | { 9 | client::String* escaped = new client::String("V\bery evil\t string\n\xff"); 10 | assertEqual(escaped->get_length(), 20, "String literal support"); 11 | } 12 | -------------------------------------------------------------------------------- /tests/unit/codegen/fptoi.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | template 9 | constexpr I roundTrip(I i) 10 | { 11 | F f = static_cast(i); 12 | return static_cast(f); 13 | } 14 | template 15 | void testFPToI() 16 | { 17 | constexpr I maxExpected = roundTrip(max); 18 | I maxi = roundTrip(unitBlackBox(max)); 19 | assertEqual(maxi, maxExpected, "fptoi support 1/N"); 20 | } 21 | void webMain() 22 | { 23 | testFPToI(); 24 | testFPToI(); 25 | testFPToI(); 26 | testFPToI(); 27 | testFPToI(); 28 | testFPToI(); 29 | testFPToI(); 30 | testFPToI(); 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/codegen/nested_lambda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace [[cheerp::genericjs]] client 4 | { 5 | class ClientClass : public Object 6 | { 7 | public: 8 | ClientClass(const int N); 9 | void doTest(const int A); 10 | }; 11 | void someFunc(); 12 | void someFuncNested(); 13 | }; 14 | 15 | class [[cheerp::genericjs]][[cheerp::jsexport]] ClientClass 16 | { 17 | public: 18 | ClientClass(const int N) : n(N) {} 19 | void doTest(const int A) 20 | { 21 | assertEqual(A, n, "Calls through lambda"); 22 | } 23 | private: 24 | const int n; 25 | }; 26 | 27 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFunc() 28 | { 29 | auto lambda = [](client::ClientClass* instance) -> void 30 | { 31 | instance->doTest(123); 32 | }; 33 | 34 | client::ClientClass* X = new client::ClientClass(123); 35 | lambda(X); 36 | } 37 | 38 | void [[cheerp::genericjs]][[cheerp::jsexport]] someFuncNested() 39 | { 40 | auto lambda_outer = [](client::ClientClass* instance) -> void 41 | { 42 | auto lambda = [](client::ClientClass* a) -> void 43 | { 44 | a->doTest(42); 45 | }; 46 | 47 | lambda(instance); 48 | lambda(instance); 49 | }; 50 | 51 | client::ClientClass* X = new client::ClientClass(42); 52 | lambda_outer(X); 53 | } 54 | 55 | int main() 56 | { 57 | someFunc(); 58 | someFuncNested(); 59 | } 60 | -------------------------------------------------------------------------------- /tests/unit/codegen/reverse_iter.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2022 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | const int N = 2301; 8 | 9 | float a[N]; 10 | 11 | int main() 12 | { 13 | for (int i=0; i=0; i--) 16 | a[i] += a[i+1] * (i%2 ? 1.0 : -1.0); 17 | 18 | float acc = 123; 19 | int numSamples = (int)(N*0.91); 20 | for(int i = 0; i < numSamples; ++i) 21 | acc += a[N-1-i]; 22 | 23 | assertEqual((int)a[0], (int)4302680, "Reverse iteration of static array 1/2"); 24 | assertEqual((int)acc, (int)1649593728, "Reverse iteration of static array 2/2"); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/codegen/structbase.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct a { 4 | short b; 5 | unsigned int c; 6 | int d; 7 | }; 8 | struct { 9 | struct a b; 10 | } e = {9, 8}; 11 | int *f = &e.b.d; 12 | void g() { *f = 234; } 13 | 14 | int main() { 15 | g(); 16 | assertEqual(e.b.c, 8u, "expected to be equal"); 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/codegen/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | //Test recursive dependency in PHIs 10 | int a = 1; 11 | int b = 2; 12 | 13 | for(volatile int i=0;i<3;i++) 14 | { 15 | int c=a; 16 | a=b; 17 | b=c; 18 | } 19 | 20 | assertEqual(a, 2, "PHI support 1/2"); 21 | assertEqual(b, 1, "PHI support 2/2"); 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/codegen/test10.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | volatile double d=1; 10 | const double epsilon = 1.0e-10; 11 | assertEqual(d<1.0+epsilon,true,"High precision double literals"); 12 | } 13 | -------------------------------------------------------------------------------- /tests/unit/codegen/test11.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int p; 10 | }; 11 | 12 | int g = 43; 13 | 14 | int* __attribute__((noinline)) selectorFunc(A* a, int d) 15 | { 16 | if(d) 17 | return &g; 18 | else 19 | return &a->p; 20 | } 21 | 22 | void webMain() 23 | { 24 | A a; 25 | a.p = 42; 26 | volatile bool cond=false; 27 | int* p2 = 0; 28 | if(cond) 29 | p2 = selectorFunc(&a, 1); 30 | else 31 | p2 = selectorFunc(&a, 0); 32 | a.p = 44; 33 | volatile int p3 = *p2; 34 | assertEqual((int)p3, 44, "GEP aliasing"); 35 | } 36 | -------------------------------------------------------------------------------- /tests/unit/codegen/test12.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void webMain() 10 | { 11 | const char* str="-0.832050323486328125"; 12 | double ret=strtod(str, NULL); 13 | assertEqual(ret,-0.832050323486328125,"High precision strtod"); 14 | } 15 | -------------------------------------------------------------------------------- /tests/unit/codegen/test13.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void webMain() 10 | { 11 | setlocale(LC_ALL, "C.UTF-8"); 12 | const char * h = "hello"; 13 | mbstate_t s{}; 14 | size_t ret=mbsrtowcs(0, &h, 0, &s); 15 | 16 | assertEqual(ret, 5, "Multibyte string support"); 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/codegen/test14.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int i; 10 | }; 11 | 12 | struct B 13 | { 14 | A* a; 15 | }; 16 | 17 | void webMain() 18 | { 19 | volatile B b; 20 | b.a = new A; 21 | b.a->i = 42; 22 | volatile A* a2 = new A[10]; 23 | for(int i=0;i<10;i++) 24 | a2[i].i = i; 25 | assertEqual(b.a->i, 42, "Accessing member of stack allocated struct"); 26 | assertEqual((int)a2[8].i, 8, "Accessing member of heap allocated struct"); 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/codegen/test15.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int a; 10 | }; 11 | 12 | struct B 13 | { 14 | A* a; 15 | }; 16 | 17 | void __attribute__((noinline)) func(A** a) 18 | { 19 | *a = NULL; 20 | } 21 | 22 | void webMain() 23 | { 24 | B b { new A() }; 25 | func(&b.a); 26 | A* volatile a2 = b.a; 27 | assertEqual((A *)a2, (A *)nullptr, "Pointers to structs in structs"); 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/codegen/test16.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | volatile float a = -42.0f; 11 | volatile float b = fabsf(a); 12 | assertEqual((float)b, 42.f, "fabs"); 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/codegen/test17.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | volatile unsigned int a=0x7fffffff; 10 | a *= 2; 11 | a += 1; 12 | volatile int b=0; 13 | b--; 14 | unsigned int tmp1=a; 15 | int tmp2=b; 16 | assertEqual(tmp1 == tmp2, true,"Signed arithmetic 1"); 17 | volatile unsigned short a2=0xffff; 18 | volatile short b2=0; 19 | b2--; 20 | unsigned short tmp3=a2; 21 | short tmp4=b2; 22 | assertEqual(tmp3,tmp4,"Signed arithmetic 2"); 23 | assertEqual(tmp3,tmp4,"Signed arithmetic 3"); 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/codegen/test18.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | int* a = new int[10]; 10 | int count1 = 0; 11 | for(int* i = a+1; i < a+8; i++) 12 | count1++; 13 | int count2 = 0; 14 | for(int* i = a+1; i <= a+8; i++) 15 | count2++; 16 | int count3 = 0; 17 | for(int* i = a+8; i > a+1; i--) 18 | count3++; 19 | int count4 = 0; 20 | for(int* i = a+8; i >= a+1; i--) 21 | count4++; 22 | int count5 = 0; 23 | for(int* i = a+8; i > a; i--) 24 | count5++; 25 | int count6 = 0; 26 | for(int* i = a+8; i >= a; i--) 27 | count6++; 28 | int count7 = 0; 29 | for(int* i = a+1; i != a+8; i++) 30 | count7++; 31 | int count8 = 0; 32 | for(int* i = a+8; i != a; i--) 33 | count8++; 34 | assertEqual(count1,7,"Scalar evolution for pointers 1/8"); 35 | assertEqual(count2,8,"Scalar evolution for pointers 2/8"); 36 | assertEqual(count3,7,"Scalar evolution for pointers 3/8"); 37 | assertEqual(count4,8,"Scalar evolution for pointers 4/8"); 38 | assertEqual(count5,8,"Scalar evolution for pointers 5/8"); 39 | assertEqual(count6,9,"Scalar evolution for pointers 6/8"); 40 | assertEqual(count7,7,"Scalar evolution for pointers 7/8"); 41 | assertEqual(count8,8,"Scalar evolution for pointers 8/8"); 42 | } 43 | -------------------------------------------------------------------------------- /tests/unit/codegen/test19.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | int testSwitch(volatile int16_t* i) 8 | { 9 | switch((int16_t)*i) 10 | { 11 | case (int16_t)10: 12 | return 0; 13 | case (int16_t)-1: 14 | return 1; 15 | default: 16 | return 2; 17 | } 18 | } 19 | 20 | void webMain() 21 | { 22 | volatile int16_t a = 0xffff; 23 | assertEqual(testSwitch(&a), 1, "Switch on 16-bit integers 1/3"); 24 | a = -1; 25 | assertEqual(testSwitch(&a), 1, "Switch on 16-bit integers 2/3"); 26 | a = 10; 27 | assertEqual(testSwitch(&a), 0, "Switch on 16-bit integers 3/3"); 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/codegen/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void webMain() 10 | { 11 | //Test printf of a very small negative float 12 | union { 13 | float f; 14 | unsigned int i; 15 | } tmp; 16 | tmp.i = 0xb3428184; 17 | char buf[20]; 18 | sprintf(buf,"%f",tmp.f); 19 | 20 | assertEqual(strcmp(buf,"-0.000000"), 0, "Printf of very small negative float"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/codegen/test20.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | // Test merging of arrays of the same type inside structs 8 | 9 | struct A 10 | { 11 | char* p1[4]; 12 | char c1[4]; 13 | char* p2[3]; 14 | char c2[3]; 15 | }; 16 | 17 | A globalA = { { NULL, NULL, NULL, NULL }, { 0, 1, 2, 3} }; 18 | 19 | void webMain() 20 | { 21 | A a; 22 | for(int i=0;i<4;i++) 23 | { 24 | a.c1[i] = i; 25 | a.p1[i] = &a.c1[i]; 26 | } 27 | for(int i=0;i<3;i++) 28 | { 29 | a.c2[i] = i+10; 30 | a.p2[i] = &a.c2[i]; 31 | } 32 | // The next lines can succeed only if p2 is merged in p1 33 | char** tmp1=a.p1; 34 | assertEqual(tmp1[4], &a.c2[0], "Merging arrays in structs 1/4"); 35 | assertEqual(*tmp1[4], a.c2[0], "Merging arrays in structs 2/4"); 36 | // The next line can succeed only if c2 is merged in c1 37 | char* tmp2=a.c1; 38 | assertEqual(tmp2[4], a.c2[0], "Merging arrays in structs 3/4"); 39 | assertEqual(tmp2[4], (char)10, "Merging arrays in structs 4/4"); 40 | } 41 | -------------------------------------------------------------------------------- /tests/unit/codegen/test22.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | extern "C" 8 | { 9 | long long __divti3 (unsigned long long numerator, unsigned long long denominator); 10 | long long __modti3 (unsigned long long numerator, unsigned long long denominator); 11 | long long __udivti3 (unsigned long long numerator, unsigned long long denominator); 12 | long long __umodti3 (unsigned long long numerator, unsigned long long denominator); 13 | } 14 | 15 | void webMain() 16 | { 17 | // Test runtime based 64-bit division and module 18 | unsigned long long a = 1LL << 32; 19 | unsigned long long b = 1000000000; 20 | long long udiv = __udivti3(a, b); 21 | assertEqual(udiv, 4LL, "Runtime based division and modulo 1/N"); 22 | long long umod = __umodti3(a, b); 23 | assertEqual(umod, 294967296LL, "Runtime based division and modulo 2/N"); 24 | long long c = -a; 25 | long long sdiv = __divti3(c, b); 26 | assertEqual((long)sdiv, -4L, "Runtime based division and modulo 3/N"); 27 | long long smod = __modti3(c, b); 28 | assertEqual((long)smod, -294967296L, "Runtime based division and modulo 4/N"); 29 | long long d = -1LL; 30 | long long udiv2 = __udivti3(d, d); 31 | assertEqual(udiv2, 1LL, "Runtime based division and modulo 5/N"); 32 | } 33 | -------------------------------------------------------------------------------- /tests/unit/codegen/test23.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | struct A 9 | { 10 | struct A* a; 11 | }; 12 | 13 | void webMain() 14 | { 15 | struct A a; 16 | a.a = &a; 17 | assertEqual(a.a, &a, "Support recursive pointer in struct"); 18 | } 19 | -------------------------------------------------------------------------------- /tests/unit/codegen/test24.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technologies 3 | //===---------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | std::string buffer; 10 | int val = 100; 11 | uint64_t d = 1; 12 | while (d <= val) 13 | d *= 10; 14 | 15 | while (d > 10) 16 | { 17 | d /= 10; 18 | int x = val / d; 19 | buffer.push_back('0'+x); 20 | val -= x * d; 21 | } 22 | buffer.push_back('0' + val); 23 | 24 | assertEqual(buffer.c_str(), "100", "Converting 64-bit integers to string 1/6"); 25 | 26 | char charBuffer[32]; 27 | d = 100; 28 | sprintf(charBuffer,"%llu",d); 29 | assertEqual(strcmp(charBuffer, "100"), 0, "Converting 64-bit integers to string 2/6"); 30 | d = 0xffffffffLL; 31 | sprintf(charBuffer,"%llu",d); 32 | assertEqual(strcmp(charBuffer, "4294967295"), 0, "Converting 64-bit integers to string 3/6"); 33 | sprintf(charBuffer,"%lli",d); 34 | assertEqual(strcmp(charBuffer, "4294967295"), 0, "Converting 64-bit integers to string 4/6"); 35 | d = 0xffffffffffffffffLL; 36 | sprintf(charBuffer,"%llu",d); 37 | assertEqual(strcmp(charBuffer, "18446744073709551615"), 0, "Converting 64-bit integers to string 5/6"); 38 | sprintf(charBuffer,"%lli",d); 39 | assertEqual(strcmp(charBuffer, "-1"), 0, "Converting 64-bit integers to string 6/6"); 40 | 41 | sscanf("100", "%llu", &d); 42 | assertEqual(d, 100LL, "Converting string to 64-bit integers 1/"); 43 | sscanf("4294967295", "%llu", &d); 44 | assertEqual(d, 4294967295LL, "Converting string to 64-bit integers 2/"); 45 | sscanf("4294967295", "%lli", &d); 46 | assertEqual(d, 4294967295LL, "Converting string to 64-bit integers 3/"); 47 | sscanf("18446744073709551615", "%llu", &d); 48 | assertEqual(d, 0xffffffffffffffffLL, "Converting string to 64-bit integers 4/"); 49 | sscanf("-1", "%lli", &d); 50 | assertEqual(d, 0xffffffffffffffffLL, "Converting string to 64-bit integers 5/"); 51 | } 52 | -------------------------------------------------------------------------------- /tests/unit/codegen/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | const char test[] = {0, 1, 4, 5*2}; 10 | assertEqual(test[2], 4, "Constant arrays in methods"); 11 | } 12 | -------------------------------------------------------------------------------- /tests/unit/codegen/test4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | int * foo(int * a,int * b) 8 | { 9 | a[2] = b[1]; 10 | b[2] = a[1]; 11 | 12 | return a[1] < b[1] ? a + 1 : b+1; 13 | } 14 | 15 | void webMain() 16 | { 17 | int A[] = {1,2,3}; 18 | int B[] = {7,5,4}; 19 | 20 | int * C = foo(A,B); 21 | 22 | //A == {1,2,5} 23 | //B == {7,5,2} 24 | //C == &A[1] 25 | 26 | //TODO put intrinsic to assert the correct pointer type 27 | assertEqual(C,&A[1],"Pointer equality comparison"); 28 | assertEqual(A[2],5,"Store via pointer inside a function"); 29 | assertEqual(B[2],2,"Store via pointer inside a function"); 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/codegen/test5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | int v[] = {0,1,2,3}; 10 | memmove(v + 1, v, 3*sizeof(int)); 11 | 12 | assertEqual(v[0],0,"Memmove backward 1/4"); 13 | assertEqual(v[1],0,"Memmove backward 2/4"); 14 | assertEqual(v[2],1,"Memmove backward 3/4"); 15 | assertEqual(v[3],2,"Memmove backward 4/4"); 16 | } 17 | -------------------------------------------------------------------------------- /tests/unit/codegen/test6.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | // Test alloca merging on libc pow. It is implemented using tons of unions. 9 | 10 | void webMain() 11 | { 12 | volatile float val = 2.0f; 13 | float ret = powf(val, 10.0f); 14 | assertEqual(ret, 1024.0f, "libc pow"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/codegen/test7.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | std::array arr({{1, 2}}); 10 | 11 | void webMain() 12 | { 13 | int index = 0; 14 | for (const auto & elem: arr) 15 | { 16 | if(index==0) 17 | assertEqual(elem, 1, "Range for on std::array 1/3"); 18 | else if(index==1) 19 | assertEqual(elem, 2, "Range for on std::array 2/3"); 20 | index++; 21 | } 22 | assertEqual(index, 2, "Range for on std::array 3/3"); 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/codegen/test8.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | int a; 11 | A(int i=42):a(i) 12 | { 13 | } 14 | }; 15 | 16 | class B: public A 17 | { 18 | public: 19 | float f; 20 | B(int i=43):A(i),f(2.3f) 21 | { 22 | } 23 | }; 24 | 25 | class C 26 | { 27 | public: 28 | B b; 29 | C():b(44) 30 | { 31 | } 32 | }; 33 | 34 | class D 35 | { 36 | public: 37 | B* b; 38 | D():b(NULL) 39 | { 40 | b = new B(45); 41 | } 42 | }; 43 | 44 | void webMain() 45 | { 46 | A a; 47 | B b; 48 | C c; 49 | D d; 50 | assertEqual(a.a, 42, "Struct flattening 1/5"); 51 | assertEqual(b.a, 43, "Struct flattening 2/5"); 52 | assertEqual(b.f, 2.3f, "Struct flattening 3/5"); 53 | assertEqual(c.b.a, 44, "Struct flattening 4/5"); 54 | assertEqual(d.b->a, 45, "Struct flattening 5/5"); 55 | } 56 | -------------------------------------------------------------------------------- /tests/unit/codegen/test9.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void __attribute__((noinline)) indirect_mul2(int* r, int* a) 8 | { 9 | *r = 0; 10 | *r = (*a+*r) * 2; 11 | } 12 | 13 | void webMain() 14 | { 15 | int a = 2; 16 | int r; 17 | 18 | indirect_mul2(&r, &a); 19 | assertEqual((float)r, 4.0f, "Indirect multiply"); 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/codegen/unsignedTrunc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace [[cheerp::genericjs]] client 4 | { 5 | bool someFunc(); 6 | } 7 | 8 | [[cheerp::jsexport]] 9 | int someValue(unsigned char a) 10 | { 11 | unsigned char X(a); 12 | X+=23; 13 | 14 | unsigned char d; 15 | 16 | if (client::someFunc()) 17 | d = (unsigned char) (X & (unsigned char)12); 18 | else 19 | d = (unsigned char)X; 20 | 21 | return d; 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/codegen/unsignedTrunc.testing.js: -------------------------------------------------------------------------------- 1 | global.someFunc = function() 2 | { 3 | return false; 4 | } 5 | 6 | function onInstantiation(_) 7 | { 8 | if (_.someValue(255) < 255) 9 | console.log("Module export", "SUCCESS"); 10 | else 11 | console.log("Module export", "FAILURE"); 12 | } 13 | -------------------------------------------------------------------------------- /tests/unit/codegen/variadic.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | int variadicSumImpl(va_list args) 10 | { 11 | int ret = 0; 12 | while(char* i = va_arg(args, char*)) 13 | { 14 | ret += *i; 15 | } 16 | return ret; 17 | } 18 | 19 | int variadicSum(int a, ...) 20 | { 21 | int ret = 0; 22 | va_list args; 23 | va_start(args,a); 24 | ret = variadicSumImpl(args); 25 | va_end(args); 26 | return ret; 27 | } 28 | int variadicSumTwice(int a, ...) 29 | { 30 | int ret = 0; 31 | va_list args; 32 | va_start(args,a); 33 | va_list copy; 34 | va_copy(copy,args); 35 | ret = variadicSumImpl(args); 36 | va_end(args); 37 | ret += variadicSumImpl(copy); 38 | va_end(copy); 39 | return ret; 40 | } 41 | void webMain() 42 | { 43 | int i = NULL; 44 | int *p = NULL; 45 | char a = 1; 46 | char b = 2; 47 | char c = 3; 48 | char d = 4; 49 | int r1 = variadicSum(NULL,&a,&b,&c,&d,NULL); 50 | assertEqual(r1, 10, "Passing NULL to variadic call 1/2"); 51 | int r2 = variadicSum(NULL,NULL); 52 | assertEqual(r2, 0, "Passing NULL to variadic call 2/2"); 53 | int r3 = variadicSumTwice(NULL, &a,&b,&c,&d, NULL); 54 | assertEqual(r3, 20, "Using va_copy in variadic call"); 55 | } 56 | -------------------------------------------------------------------------------- /tests/unit/coroutines/cast-promise.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | #include 8 | 9 | struct Task { 10 | struct promise_type { 11 | // Ensure `promise_type` does not fit inside a register, so that we get an 12 | // error if the conversion described below is selected. 13 | char _[1024]; 14 | 15 | Task get_return_object(); 16 | std::suspend_never initial_suspend() const noexcept; 17 | std::suspend_never final_suspend() const noexcept; 18 | void return_void(); 19 | }; 20 | }; 21 | 22 | // Tries to construct `Task::promise_type` using the generic conversion 23 | // `operator T()` on `client::_Any`. The conversion should not be considered by 24 | // overload resolution because of SFINAE. 25 | Task foo(const client::Object&) { 26 | co_return; 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/dom/max.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2019-2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | // Test variadic client class 11 | double m1 = client::Math.max(1.0f, 10u); 12 | assertEqual(m1, 10.0, "Variadic Math.max 1/3"); 13 | double m2 = client::Math.max(20u, 30u); 14 | assertEqual(m2, 30.0, "Variadic Math.max 2/3"); 15 | double m3 = client::Math.max(0.1, 0.2); 16 | assertEqual(m3, 0.2, "Variadic Math.max 3/3"); 17 | client::console.log("Variadic", "console.log", ":", "SUCCESS"); 18 | } 19 | -------------------------------------------------------------------------------- /tests/unit/dom/noconstructor.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace client 10 | { 11 | class FakeClientObj: public Object 12 | { 13 | public: 14 | void set_val(int); 15 | int get_val(); 16 | }; 17 | } 18 | 19 | void webMain() 20 | { 21 | client::FakeClientObj* o = new client::FakeClientObj(); 22 | o->set_val(42); 23 | assertEqual(o->get_val(), 42, "Creating client object that do not have a constructor"); 24 | client::TArray* ta = new client::TArray(); 25 | assertEqual(ta->get_length(), 0, "Creating template array wrapper type"); 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/dom/objapi.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | client::Object* o = new client::Object(); 11 | o->set_("prop1", new client::Number(1)); 12 | o->set_("prop2", new client::String("val")); 13 | o->set_("prop3", nullptr); 14 | client::Array* ar = client::Object::values(o); 15 | 16 | assertEqual(ar->get_length(), 3, "Object::value 1/4"); 17 | assertEqual((int)*(*ar)[0], 1, "Object::value 2/4"); 18 | assertEqual((*ar)[1], new client::String("val"), "Object::value 3/4"); 19 | assertEqual((*ar)[2], nullptr, "Object::value 4/4"); 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/dom/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | //Test Object to Number conversion 11 | client::Object* o = client::JSON.parse("42.42"); 12 | double dval = (double)*o; 13 | assertEqual(dval, 42.42, "Object to Number"); 14 | } 15 | -------------------------------------------------------------------------------- /tests/unit/dom/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | //Test string constructor 11 | client::String* ret=client::String::fromCharCode(0x30); 12 | assertEqual(ret->charCodeAt(0), 0x30, "String::fromCharCode"); 13 | 14 | ret=new client::String("1"); 15 | assertEqual(ret->charCodeAt(0), 0x31, "String from const char*"); 16 | } 17 | -------------------------------------------------------------------------------- /tests/unit/dom/test4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | //Test various variadic methods 11 | client::console.log("Variadic methods 1/4 : SUCCESS"); 12 | client::console.log(client::String("Variadic methods 2/4 : SUCCESS")); 13 | client::console.log("Variadic methods 3/4 :","SUCCESS"); 14 | client::console.log(client::String("Variadic methods 4/4 :"),client::String("SUCCESS")); 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/dom/test5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include "tests.h" 8 | 9 | void webMain() 10 | { 11 | client::String* a1 = new client::String("Test"); 12 | client::String* a2 = new client::String("Test"); 13 | 14 | assertEqual(a1==a2, true, "Comparing client objects"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/dom/test6.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include "tests.h" 8 | 9 | client::String* volatile globalString; 10 | 11 | void webMain() 12 | { 13 | client::String* a1 = new client::String("Test"); 14 | globalString = a1; 15 | 16 | assertEqual(globalString==a1, true, "Comparing client objects from globals"); 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/dom/test7.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014-2022 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | #include "tests.h" 9 | 10 | int callbackCount=0; 11 | std::set calledBack; 12 | 13 | 14 | void plainFunction() 15 | { 16 | assertEqual(calledBack.insert(callbackCount++).second, 1, "Calling back plain functions"); 17 | } 18 | 19 | class Functor 20 | { 21 | private: 22 | int data; 23 | client::EventListener** e; 24 | public: 25 | static int destructorCalled; 26 | Functor(client::EventListener** e):data(42), e(e) 27 | { 28 | } 29 | ~Functor() 30 | { 31 | destructorCalled++; 32 | } 33 | void operator()() 34 | { 35 | assertEqual(data, 42, "Calling back functors 1/3"); 36 | assertEqual(calledBack.insert(callbackCount++).second, 1, "Calling back functors 2/3"); 37 | cheerp::freeCallback(*e); 38 | } 39 | }; 40 | 41 | int Functor::destructorCalled=0; 42 | 43 | void webMain() 44 | { 45 | // Test various ways of passing callbacks to JavaScript code 46 | setTimeout(cheerp::Callback(plainFunction), 0); 47 | client::EventListener** c = new client::EventListener*[1]; 48 | *c = cheerp::Callback(Functor(c)); 49 | setTimeout(*c, 0); 50 | setTimeout(cheerp::Callback([]() 51 | { 52 | assertEqual(calledBack.insert(callbackCount++).second, 1, "Calling back non-capturing lambdas"); 53 | }), 0); 54 | int capturedInt=43; 55 | setTimeout(cheerp::Callback([capturedInt]() 56 | { 57 | assertEqual(capturedInt, 43, "Calling back capturing lambdas 1/2"); 58 | assertEqual(calledBack.insert(callbackCount++).second, 1, "Calling back capturing lambdas 2/2"); 59 | assertEqual(Functor::destructorCalled | 3, 3, "Calling back functors 3/3"); 60 | }), 0); 61 | } 62 | -------------------------------------------------------------------------------- /tests/unit/dom/test8.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include "tests.h" 8 | 9 | void webMain() 10 | { 11 | // Test square parenthesis operator and set_ 12 | client::Object* t = new client::Object(); 13 | t->set_(client::String("a"), new client::String("b")); 14 | 15 | client::String* retrieved = (client::String*)(*t)[client::String("a")]; 16 | assertEqual(retrieved, new client::String("b"), "Object::operator[]"); 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/dom/test9.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | //Test JS Map 11 | client::Map* tmap = new client::Map; 12 | 13 | tmap->set(42, 42); 14 | tmap->set(45, 74); 15 | assertEqual(tmap->get(42), 42, "JS TMap::get 1/2"); 16 | assertEqual(tmap->get(45), 74, "JS TMap::get 2/2"); 17 | 18 | assertEqual(tmap->get_size(), 2, "JS TMap::get_size() 1/2"); 19 | tmap->set(45, -42); 20 | assertEqual(tmap->get_size(), 2, "JS TMap::get_size() 2/2"); 21 | 22 | 23 | assertEqual(tmap->has(42), true, "JS TMap::has 1/2"); 24 | assertEqual(tmap->has(43), false, "JS TMap::has 2/2"); 25 | 26 | assertEqual(tmap->delete_(445), false, "JS TMap::get_delete_ 1/2"); 27 | assertEqual(tmap->delete_(42), true, "JS TMap::get_delete_ 2/2"); 28 | 29 | tmap->set(1,1); 30 | tmap->set(100213, 0); 31 | tmap->set(123123, 23); 32 | static int sum; 33 | sum = 0; 34 | tmap->forEach(cheerp::Callback([](int a, int b){ 35 | sum += a; 36 | })); 37 | assertEqual(sum, 1 + 0 + 23 - 42, "JS Tmap::forEach 1/1"); 38 | 39 | tmap->clear(); 40 | assertEqual(tmap->get_size(), 0, "JS TMap::clear 1/1"); 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/dom/utf8.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | void webMain() 11 | { 12 | const char ascii[] = "a"; 13 | uint32_t ascii_codepoint = 97; 14 | client::String* ascii_converted = client::String::fromUtf8(ascii); 15 | assertEqual(ascii_codepoint, (uint32_t)ascii_converted->charCodeAt(0), "UTF-8 support: 1/5"); 16 | 17 | const char accent[] = "è"; 18 | uint32_t accent_codepoint = 232; 19 | client::String* accent_converted = client::String::fromUtf8(accent); 20 | assertEqual(accent_codepoint, (uint32_t)accent_converted->charCodeAt(0), "UTF-8 support: 2/5"); 21 | 22 | const char cjk[] = "不"; 23 | uint32_t cjk_codepoint = 19981; 24 | client::String* cjk_converted = client::String::fromUtf8(cjk); 25 | assertEqual(cjk_codepoint, (uint32_t)cjk_converted->charCodeAt(0), "UTF-8 support: 3/5"); 26 | 27 | const char emoji[] = "🤔"; 28 | uint32_t emoji_codepoint1 = 55358; 29 | uint32_t emoji_codepoint2 = 56596; 30 | client::String* emoji_converted = client::String::fromUtf8(emoji); 31 | assertEqual(emoji_codepoint1, (uint32_t)emoji_converted->charCodeAt(0), "UTF-8 support: 4/5"); 32 | assertEqual(emoji_codepoint2, (uint32_t)emoji_converted->charCodeAt(1), "UTF-8 support: 5/5"); 33 | } 34 | -------------------------------------------------------------------------------- /tests/unit/downcast/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct C 8 | { 9 | float c; 10 | C():c(3){} 11 | }; 12 | 13 | struct B 14 | { 15 | int b; 16 | B():b(1){} 17 | }; 18 | 19 | struct A: public B, public C 20 | { 21 | int a; 22 | A():a(2){} 23 | }; 24 | 25 | void webMain() 26 | { 27 | A a; 28 | B* volatile b=&a; 29 | C* volatile c=&a; 30 | A* volatile a2=static_cast(b); 31 | assertEqual(a2->a, 2, "Downcast 1/2"); 32 | A* volatile a3=static_cast(c); 33 | assertEqual(a3->a, 2, "Downcast 2/2"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/exceptions/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | [[cheerp::wasm]] 8 | bool abiCatch = false; 9 | [[cheerp::wasm]] 10 | bool otherCatch = false; 11 | 12 | [[cheerp::wasm]] 13 | void doThrow() 14 | { 15 | throw 1; 16 | } 17 | 18 | [[cheerp::genericjs]] 19 | void middle() 20 | { 21 | try { 22 | doThrow(); 23 | } catch(int i) { 24 | otherCatch = true; 25 | throw; 26 | } 27 | } 28 | 29 | [[cheerp::wasm]] 30 | void doCatch() 31 | { 32 | try { 33 | middle(); 34 | } catch(int i) { 35 | abiCatch = true; 36 | } 37 | } 38 | [[cheerp::wasm]] 39 | void webMain() 40 | { 41 | doCatch(); 42 | assertEqual(otherCatch, true, "Non-ABI section can catch exceptions and rethrow 1/2"); 43 | assertEqual(abiCatch, true, "Non-ABI section can catch exceptions and rethrow 2/2"); 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/ffi/i64.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2020 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | using u64 = unsigned long long; 8 | 9 | [[cheerp::wasm]] 10 | u64 process_wasm(u64 a, u64 b) { 11 | return a+b; 12 | } 13 | [[cheerp::genericjs]] 14 | u64 wrapper_genericjs(u64 a, u64 b) { 15 | return process_wasm(a,b); 16 | } 17 | [[cheerp::genericjs]] 18 | u64 process_genericjs(u64 a, u64 b) { 19 | return a+b; 20 | } 21 | [[cheerp::wasm]] 22 | u64 wrapper_wasm(u64 a, u64 b) { 23 | return process_genericjs(a,b); 24 | } 25 | 26 | void webMain() 27 | { 28 | u64 a = unitBlackBox(0x0f0f0f0f0f0f0f0f); 29 | u64 b = unitBlackBox(0xf0f0f0f0f0f0f0f0); 30 | assertEqual(wrapper_wasm(a,b), unitBlackBox(0xffffffffffffffff), "ffi pointer interoperation 1/2"); 31 | assertEqual(wrapper_genericjs(a,b), unitBlackBox(0xffffffffffffffff), "ffi pointer interoperation 2/2"); 32 | } 33 | -------------------------------------------------------------------------------- /tests/unit/ffi/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void process(std::vector& v) { 9 | int k = 0; 10 | for(int i = 0; i < v.size(); i++) { 11 | v[i] += k; 12 | k = v[i]; 13 | } 14 | } 15 | 16 | template 17 | void push_back_wrapper(std::vector& v, T i) 18 | { 19 | v.push_back(i); 20 | } 21 | [[cheerp::genericjs]] 22 | int generic() { 23 | std::vector v; 24 | for(int i = 0; i < 5; i++) { 25 | push_back_wrapper(v, i); 26 | } 27 | process(v); 28 | int ret = v[4]; 29 | return ret; 30 | } 31 | void webMain() 32 | { 33 | assertEqual(generic(), 10, "ffi pointer interoperation"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/ffi/test2.cpp: -------------------------------------------------------------------------------- 1 | 2 | //===---------------------------------------------------------------------===// 3 | // Copyright 2017 Leaning Technlogies 4 | //===----------------------------------------------------------------------===// 5 | 6 | #include 7 | 8 | struct Foo { 9 | int i; 10 | Foo* next; 11 | Foo(int i, Foo* next): i(i), next(next) 12 | {} 13 | }; 14 | 15 | [[cheerp::genericjs]] 16 | int process_foo(const Foo& f) 17 | { 18 | return f.i+ (f.next == nullptr? 0 : process_foo(*f.next)); 19 | } 20 | 21 | void webMain() 22 | { 23 | Foo f(1,new Foo(2, new Foo(3, nullptr))); 24 | assertEqual(process_foo(f), 6, "ffi store support for RAW pointers"); 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/ffi/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2019 Leaning Technlogies 3 | //===---------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | [[cheerp::genericjs]] client::String* s = new client::String("aaa"); 13 | std::string ss = "bbb"; 14 | 15 | int main() 16 | { 17 | assertEqual(ss, std::string("bbb"), "Static constructors 1/2"); 18 | return 1; 19 | } 20 | 21 | [[cheerp::genericjs]] void webMain() 22 | { 23 | main(); 24 | client::String* i = new client::String("aaa"); 25 | assertEqualImpl(s == i, "Static constructor 2/2"); 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/globals/betterconst.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | char c; 10 | }; 11 | 12 | struct B: public A 13 | { 14 | float f; 15 | }; 16 | 17 | 18 | B b; 19 | 20 | A* volatile a1 = &b; 21 | 22 | char* volatile c1 = &b.c; 23 | 24 | struct C 25 | { 26 | A a; 27 | float f; 28 | }; 29 | 30 | C c = { { 'A' }, 42.0f }; 31 | 32 | A* volatile a2 = &c.a; 33 | 34 | char* volatile c2 = &c.a.c; 35 | 36 | float* volatile f2 = &c.f; 37 | 38 | void* volatile v = &b; 39 | 40 | void webMain() 41 | { 42 | b.c = 'A'; 43 | b.f = 42.0f; 44 | assertEqual(a1->c, 'A', "Better generation of constant init for globals 1/6"); 45 | assertEqual(*c1, 'A', "Better generation of constant init for globals 2/6"); 46 | 47 | assertEqual(a2->c, 'A', "Better generation of constant init for globals 3/6"); 48 | assertEqual(*c2, 'A', "Better generation of constant init for globals 4/6"); 49 | 50 | assertEqual(*f2, 42.0f, "Better generation of constant init for globals 5/6"); 51 | 52 | assertEqual(((B*)v)->f, 42.0f, "Better generation of constant init for globals 6/6"); 53 | } 54 | -------------------------------------------------------------------------------- /tests/unit/globals/globaluint16.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2022 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | uint16_t global = 123; 11 | 12 | void doSomething() 13 | { 14 | char buffer[100]; 15 | sprintf(buffer, "%d\n", global); 16 | 17 | int len = strlen(buffer); 18 | assertEqual(len < 7, true, "Globalized globals should be masked"); 19 | } 20 | 21 | int main() 22 | { 23 | for (int i=0; i<53; i++) 24 | { 25 | global *= global; 26 | doSomething(); 27 | } 28 | return global; 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/globals/initializers.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2022 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | #include 5 | #include 6 | 7 | int* p1 = (int*) malloc(900); 8 | int* p2 = (int*) calloc(1, 900); 9 | int* p3 = (int*) realloc((int*) 0, 900); 10 | 11 | int main() { 12 | assertEqual(p1!=0, true, "expected p1 memory to be allocated"); 13 | assertEqual(p2!=0, true, "expected p2 memory to be allocated"); 14 | assertEqual(p3!=0, true, "expected p3 memory to be allocated"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/globals/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int x,y; 10 | A():x(1),y(2) {} 11 | }; 12 | 13 | static A a; 14 | 15 | static int* ptrX=&a.x; 16 | 17 | void webMain() 18 | { 19 | int a=*ptrX; 20 | assertEqual(a, 1, "Access to member of global structures"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/globals/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | static char *var1[] = { "\0" }; 8 | 9 | char **var2 = &var1[0]; 10 | 11 | void webMain() 12 | { 13 | char* a=*var2; 14 | assertEqual(*a, '\0', "Access to pointers of global arrays"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/globals/test4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | const char str[] = "testStr"; 8 | 9 | struct A 10 | { 11 | const char* ptr; 12 | float f; 13 | }; 14 | 15 | A a = { str, -123.5f }; 16 | 17 | void webMain() 18 | { 19 | const char* p=a.ptr; 20 | assertEqual(*p, 't', "Access to member pointers to global array"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/globals/test5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | // Test circular dependency between global variables initializers. 6 | 7 | #include 8 | 9 | struct foo 10 | { 11 | foo * next; 12 | }; 13 | 14 | extern foo c; 15 | 16 | foo a = { &c }; 17 | foo b = { &a }; 18 | foo c = { &b }; 19 | 20 | 21 | void webMain() 22 | { 23 | assertEqual(a.next,&c,"Circular dependency in global variable initializer"); 24 | assertEqual(b.next,&a,"Circular dependency in global variable initializer"); 25 | assertEqual(c.next,&b,"Circular dependency in global variable initializer"); 26 | } 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/unit/globals/test6.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | bool funcCalled = false; 8 | 9 | void testMethod() 10 | { 11 | funcCalled = true; 12 | } 13 | 14 | void (*globalMethodPtr)() = NULL; 15 | 16 | void webMain() 17 | { 18 | if(globalMethodPtr==NULL) 19 | globalMethodPtr = testMethod; 20 | globalMethodPtr(); 21 | assertEqual(funcCalled,true,"Global function pointer"); 22 | } 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/unit/globals/test7.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct T 8 | { 9 | float p[3]; 10 | float* x; 11 | float* y; 12 | float* z; 13 | }; 14 | 15 | extern T t; 16 | 17 | T t2 = {4,5,6,&t.p[0],&t.p[1],&t.p[2]}; 18 | 19 | T t = {1,2,3,&t2.p[0],&t2.p[1],&t2.p[2]}; 20 | 21 | void webMain() 22 | { 23 | assertEqual(*t.x, 4.0f, "Member references to other members 1/6"); 24 | assertEqual(*t.y, 5.0f, "Member references to other members 2/6"); 25 | assertEqual(*t.z, 6.0f, "Member references to other members 3/6"); 26 | 27 | assertEqual(*t2.x, 1.0f, "Member references to other members 4/6"); 28 | assertEqual(*t2.y, 2.0f, "Member references to other members 5/6"); 29 | assertEqual(*t2.z, 3.0f, "Member references to other members 6/6"); 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/jsexport/array_of_structs.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2022 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | struct 11 | [[cheerp::jsexport]] 12 | OrderedStruct 13 | { 14 | static int global_id; 15 | int id; 16 | int a; 17 | int b; 18 | int someUnusedArray[100]; 19 | bool hasNext; 20 | OrderedStruct() { 21 | id = global_id++; 22 | a = id*id; 23 | b = id* a; 24 | hasNext = false; 25 | } 26 | void setHasNext() 27 | { 28 | hasNext = true; 29 | } 30 | int doComputation(int c) 31 | { 32 | return a*b*c; 33 | } 34 | static int valueOf() 35 | { 36 | return 53; 37 | } 38 | }; 39 | 40 | int OrderedStruct::global_id = 0; 41 | 42 | [[cheerp::jsexport]] 43 | OrderedStruct* getSmaller(OrderedStruct* a, OrderedStruct* b) 44 | { 45 | if (a < b) 46 | return a; 47 | return b; 48 | } 49 | 50 | const int N = 10; 51 | OrderedStruct structs[10]; 52 | 53 | [[cheerp::jsexport]] 54 | OrderedStruct* getStruct(int i) 55 | { 56 | return &structs[i]; 57 | } 58 | 59 | [[cheerp::jsexport]] 60 | OrderedStruct* getNext(OrderedStruct* x) 61 | { 62 | if (x->hasNext == false) 63 | return x; 64 | return x+1; 65 | } 66 | 67 | int main() 68 | { 69 | for (int i=0; i 6 | 7 | #include 8 | 9 | class [[cheerp::jsexport]] Cat { 10 | public: 11 | [[cheerp::genericjs]] 12 | Cat(client::String* name) : age(name->operator int()) {} 13 | int age; 14 | 15 | [[cheerp::genericjs]] 16 | ~Cat() { 17 | client::console.log("Print something to console"); 18 | } 19 | int i0() { 20 | return age * age; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /tests/unit/jsexport/cat.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | var instance = new _.Cat("2"); 4 | console.log(instance.i0()); 5 | instance.delete(); 6 | } 7 | function getPromise(_) 8 | { 9 | return _.Cat.promise; 10 | } 11 | function getExports() 12 | { 13 | return {Cat : Cat}; 14 | } 15 | -------------------------------------------------------------------------------- /tests/unit/jsexport/cheerp_pimpl_mod.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | var instance = new _.JSExportedWrapperWithDeleter(21); 4 | instance.insert(45); 5 | instance.insert(2134); 6 | var X = instance.totalInserted(); 7 | instance.deleter(); 8 | if (_.CounterAlive.numberAlive() == 0) 9 | console.log("JSExport deleter check 1/1", "SUCCESS"); 10 | else 11 | console.log("JSExport deleter check 1/1", "FAILURE"); 12 | instance.delete(); 13 | } 14 | function getPromise(_) 15 | { 16 | return _.JSExportedWrapperWithDeleter.promise; 17 | } 18 | function getExports() 19 | { 20 | return { 21 | get JSExportedWrapperWithDeleter() { 22 | return JSExportedWrapperWithDeleter; 23 | }, 24 | get CounterAlive() { 25 | return CounterAlive; 26 | } 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/jsexport/compare_pointers.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2022 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | struct [[cheerp::jsexport]] Bar; 13 | struct [[cheerp::jsexport]] Foo 14 | { 15 | int i{1}; 16 | static Foo* create() 17 | { 18 | return new Foo(); 19 | } 20 | int getI() 21 | { 22 | return i; 23 | } 24 | [[cheerp::genericjs]] 25 | bool cmp(Bar* b); 26 | }; 27 | struct [[cheerp::jsexport]] Bar 28 | { 29 | int i{1}; 30 | Foo* f; 31 | static Bar* create() 32 | { 33 | auto* b = new Bar(); 34 | auto* ff = new Foo[10]; 35 | b->f = ff; 36 | return b; 37 | } 38 | Foo* getFoo(int i) 39 | { 40 | return &f[i]; 41 | } 42 | bool cmp(Foo* f) 43 | { 44 | return &this->f[2] == &f[1]; 45 | } 46 | }; 47 | namespace [[cheerp::genericjs]] client 48 | { 49 | struct Callback: public Object 50 | { 51 | Foo* operator()(Foo* f); 52 | }; 53 | extern Callback jsFunc; 54 | } 55 | 56 | [[cheerp::genericjs]] 57 | bool Foo::cmp(Bar* b) 58 | { 59 | Foo* f1 = client::jsFunc(&this[1]); 60 | Foo* f2 = client::jsFunc(&b->f[2]); 61 | return f1 == f2; 62 | } 63 | 64 | 65 | int main() 66 | { 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /tests/unit/jsexport/compare_pointers.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | global.jsFunc = function(p) 4 | { 5 | console.log("Access jsexported object in js callback 1/1", p.getI()==1?"SUCCESS":"FAILURE"); 6 | return p; 7 | }; 8 | var b = _.Bar.create(); 9 | var f = b.getFoo(1); 10 | console.log("Compare jsexported pointers 1/2", f.cmp(b)?"SUCCESS":"FAILURE"); 11 | console.log("Compare jsexported pointers 2/2", b.cmp(f)?"SUCCESS":"FAILURE"); 12 | } 13 | function getPromise(_) 14 | { 15 | return _.Bar.promise; 16 | } 17 | function getExports() 18 | { 19 | return { 20 | get Bar() { 21 | return Bar; 22 | } 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/jsexport/empty_class.cpp: -------------------------------------------------------------------------------- 1 | class [[cheerp::jsexport]] Empty {}; 2 | 3 | class [[cheerp::jsexport]] AllPrivate { 4 | AllPrivate() {} 5 | void func() { var++; } 6 | int var; 7 | }; 8 | 9 | class [[cheerp::jsexport]] OnlyStatic { 10 | public: 11 | static void func() { var++; } 12 | static int var; 13 | }; 14 | 15 | int OnlyStatic::var = 0; 16 | 17 | int main() { 18 | Empty empty; 19 | OnlyStatic onlyStatic; 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/jsexport/empty_class.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | assert(!canConstruct(_.Empty), "new Empty()"); 4 | assert(!canConstruct(_.AllPrivate), "new AllPrivate()"); 5 | assert(!canConstruct(_.OnlyStatic), "new OnlyStatic()"); 6 | } 7 | function canConstruct(Class) 8 | { 9 | let instance; 10 | 11 | try { 12 | instance = new Class(); 13 | } catch (_) { 14 | return false; 15 | } 16 | 17 | instance.delete(); 18 | return true; 19 | } 20 | function assert(condition, message) 21 | { 22 | console.log(message, condition ? "SUCCESS" : "FAILURE"); 23 | } 24 | function getPromise(_) 25 | { 26 | return _.Empty.promise; 27 | } 28 | function getExports() 29 | { 30 | return { 31 | get Empty() { 32 | return Empty; 33 | }, 34 | get AllPrivate() { 35 | return AllPrivate; 36 | }, 37 | get OnlyStatic() { 38 | return OnlyStatic; 39 | } 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/jsexport/factory.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2020 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class [[cheerp::jsexport]][[cheerp::genericjs]] B 8 | { 9 | public: 10 | B(int k) : value(k) 11 | { 12 | counter++; 13 | } 14 | int getValue() 15 | { 16 | return value; 17 | } 18 | static int howMany() 19 | { 20 | return counter; 21 | } 22 | private: 23 | int value; 24 | static int counter; 25 | }; 26 | 27 | int B::counter = 0; 28 | 29 | [[cheerp::jsexport]][[cheerp::genericjs]] 30 | B* factoryB(int t) 31 | { 32 | return new B(t); 33 | } 34 | 35 | class [[cheerp::jsexport]][[cheerp::genericjs]] A 36 | { 37 | public: 38 | A(int X) : value(X) {} 39 | B* generateB() 40 | { 41 | B* b = new B(value); 42 | return b; 43 | } 44 | private: 45 | int value; 46 | }; 47 | 48 | [[cheerp::genericjs]]B global(23); 49 | 50 | [[cheerp::genericjs]] 51 | void webMain() 52 | { 53 | assertEqual(global.getValue(), 23, "JSExport member function 1/1"); 54 | 55 | A a(23); 56 | 57 | assertEqual(B::howMany(), 1, "JSExport generator 1/4"); 58 | B* generatedByA = a.generateB(); 59 | assertEqual(B::howMany(), 2, "JSExport generator 2/4"); 60 | __asm__("var generator = new A(12); var X = generator.generateB(); X = factoryB(213);"); 61 | assertEqual(B::howMany(), 4, "JSExport generator 3/4"); 62 | B* generatedByFactory = factoryB(1234); 63 | assertEqual(B::howMany(), 5, "JSExport generator 4/4"); 64 | } 65 | -------------------------------------------------------------------------------- /tests/unit/jsexport/global_variables.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | [[cheerp::jsexport]] 8 | int globalVariable = 1; 9 | 10 | [[cheerp::jsexport]] 11 | int getGlobalVariable() { 12 | return globalVariable; 13 | } 14 | 15 | [[cheerp::jsexport]] 16 | void setGlobalVariable(int value) { 17 | globalVariable = value; 18 | } 19 | 20 | int main() { 21 | assertEqual(1, globalVariable, "CPP: 1 == globalVariable"); 22 | assertEqual(1, getGlobalVariable(), "CPP: 1 == getGlobalVariable()"); 23 | globalVariable = 2; 24 | assertEqual(2, globalVariable, "CPP: 2 == globalVariable"); 25 | assertEqual(2, getGlobalVariable(), "CPP: 2 == getGlobalVariable()"); 26 | setGlobalVariable(3); 27 | assertEqual(3, globalVariable, "CPP: 3 == globalVariable"); 28 | assertEqual(3, getGlobalVariable(), "CPP: 3 == getGlobalVariable()"); 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/jsexport/global_variables.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | assert(3 == _.globalVariable, "JS: 3 == globalVariable"); 4 | assert(3 == _.getGlobalVariable(), "JS: 3 == getGlobalVariable()"); 5 | _.globalVariable = 4; 6 | assert(4 == _.globalVariable, "JS: 4 == globalVariable"); 7 | assert(4 == _.getGlobalVariable(), "JS: 4 == getGlobalVariable()"); 8 | _.setGlobalVariable(5); 9 | assert(5 == _.globalVariable, "JS: 5 == globalVariable"); 10 | assert(5 == _.getGlobalVariable(), "JS: 5 == getGlobalVariable()"); 11 | } 12 | function assert(condition, message) 13 | { 14 | console.log(message, condition ? "SUCCESS" : "FAILURE"); 15 | } 16 | function getPromise(_) 17 | { 18 | return _.getGlobalVariable.promise; 19 | } 20 | function getExports() 21 | { 22 | return {}; 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/jsexport/inheritance.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | struct [[cheerp::jsexport]] Interface { 6 | virtual int pureVirtualTest() = 0; 7 | 8 | virtual ~Interface() {} 9 | }; 10 | 11 | struct [[cheerp::jsexport]] Base : Interface { 12 | Base() {} 13 | 14 | int memberBaseTest() { return 1; } 15 | int memberShadowTest() { return 0; } 16 | virtual int virtualTest() { return 0; } 17 | int pureVirtualTest() override { return 0; } 18 | 19 | static int staticBaseTest() { return 1; } 20 | static int staticShadowTest() { return 0; } 21 | }; 22 | 23 | struct [[cheerp::jsexport]] Derived : Base { 24 | Derived() {} 25 | 26 | int memberDerivedTest() { return 1; } 27 | int memberShadowTest() { return 1; } 28 | int virtualTest() override { return 1; } 29 | int pureVirtualTest() override { return 1; } 30 | 31 | static int staticDerivedTest() { return 1; } 32 | static int staticShadowTest() { return 1; } 33 | }; 34 | -------------------------------------------------------------------------------- /tests/unit/jsexport/inheritance.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | let base = new _.Base(); 4 | let derived = new _.Derived(); 5 | 6 | assert(base.memberBaseTest(), "base memberBaseTest"); 7 | assert(!base.memberShadowTest(), "base memberShadowTest"); 8 | assert(!base.virtualTest(), "base virtualTest"); 9 | assert(!base.pureVirtualTest(), "base pureVirtualTest"); 10 | 11 | assert(derived.memberBaseTest(), "derived memberMemberTest"); 12 | assert(derived.memberDerivedTest(), "derived memberDerivedTest"); 13 | assert(derived.memberShadowTest(), "derived memberShadowTest"); 14 | assert(derived.virtualTest(), "derived virtualTest"); 15 | assert(derived.pureVirtualTest(), "derived pureVirtualTest"); 16 | 17 | assert(_.Base.staticBaseTest(), "base staticMemberTest"); 18 | assert(!_.Base.staticShadowTest(), "base staticMemberTest"); 19 | 20 | assert(_.Derived.staticDerivedTest(), "derived staticDerivedTest"); 21 | assert(_.Derived.staticShadowTest(), "derived staticShadowTest"); 22 | 23 | assert(!(base instanceof _.Derived), "!(base instanceof Derived)"); 24 | assert(derived instanceof _.Base, "derived instanceof Base"); 25 | 26 | base.delete(); 27 | derived.delete(); 28 | } 29 | function assert(condition, message) 30 | { 31 | console.log(message, condition ? "SUCCESS" : "FAILURE"); 32 | } 33 | function getPromise(_) 34 | { 35 | return _.Base.promise; 36 | } 37 | function getExports() 38 | { 39 | return { 40 | get Base() { 41 | return Base; 42 | }, 43 | get Derived() { 44 | return Derived; 45 | } 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /tests/unit/jsexport/invoke_functions.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2020 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | //If we need to pass functors as parameters, we need to tag [[cheerp::genercijs]] 8 | [[cheerp::jsexport]][[cheerp::genericjs]] 9 | int invokeFunction(int a, int b, int (*function)(int,int)) 10 | { 11 | return (*function)(a,b); 12 | } 13 | 14 | [[cheerp::jsexport]][[cheerp::genericjs]] 15 | int invokeFunction2(int a, int b, int (*function)(int, int,int(*x)(int,int))) 16 | { 17 | auto lambda = [](int a,int b) {return a+b;}; 18 | return (*function)(a,b,lambda); 19 | } 20 | 21 | [[cheerp::genericjs]] 22 | void webMain() 23 | { 24 | int result; 25 | 26 | __asm__("invokeFunction(50, 50, (a,b)=>{return a+b;})" : "=r"(result) :); 27 | assertEqual(result, 100, "JSExport invoke functions 1/3"); 28 | 29 | __asm__("invokeFunction(50, 50, (a,b)=>{return a*b;})" : "=r"(result) :); 30 | assertEqual(result, 2500, "JSExport invoke functions 2/3"); 31 | 32 | __asm__("invokeFunction2(50, 50, invokeFunction)" : "=r"(result) :); 33 | assertEqual(result, 100, "JSExport invoke functions 3/3"); 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/jsexport/member_variables.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct [[cheerp::jsexport]] Struct { 8 | [[cheerp::jsexport]] 9 | int memberVariable = 1; 10 | 11 | int getMemberVariable() { 12 | return memberVariable; 13 | } 14 | 15 | void setMemberVariable(int value) { 16 | memberVariable = value; 17 | } 18 | }; 19 | 20 | Struct* instance = new Struct(); 21 | 22 | [[cheerp::jsexport]] 23 | Struct* getInstance() { 24 | return instance; 25 | } 26 | 27 | int main() { 28 | assertEqual(1, instance->memberVariable, "CPP: 1 == memberVariable"); 29 | assertEqual(1, instance->getMemberVariable(), "CPP: 1 == getMemberVariable()"); 30 | instance->memberVariable = 2; 31 | assertEqual(2, instance->memberVariable, "CPP: 2 == memberVariable"); 32 | assertEqual(2, instance->getMemberVariable(), "CPP: 2 == getMemberVariable()"); 33 | instance->setMemberVariable(3); 34 | assertEqual(3, instance->memberVariable, "CPP: 3 == memberVariable"); 35 | assertEqual(3, instance->getMemberVariable(), "CPP: 3 == getMemberVariable()"); 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/jsexport/member_variables.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | assert(3 == _.getInstance().memberVariable, "JS: 3 == memberVariable"); 4 | assert(3 == _.getInstance().getMemberVariable(), "JS: 3 == getMemberVariable()"); 5 | _.getInstance().memberVariable = 4; 6 | assert(4 == _.getInstance().memberVariable, "JS: 4 == memberVariable"); 7 | assert(4 == _.getInstance().getMemberVariable(), "JS: 4 == getMemberVariable()"); 8 | _.getInstance().setMemberVariable(5); 9 | assert(5 == _.getInstance().memberVariable, "JS: 5 == memberVariable"); 10 | assert(5 == _.getInstance().getMemberVariable(), "JS: 5 == getMemberVariable()"); 11 | } 12 | function assert(condition, message) 13 | { 14 | console.log(message, condition ? "SUCCESS" : "FAILURE"); 15 | } 16 | function getPromise(_) 17 | { 18 | return _.getInstance.promise; 19 | } 20 | function getExports() 21 | { 22 | return { 23 | get getInstance() { 24 | return getInstance; 25 | } 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/jsexport/nested_variables.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | namespace Module { 8 | [[cheerp::jsexport]] 9 | int nestedVariable = 1; 10 | 11 | [[cheerp::jsexport]] 12 | int getNestedVariable() { 13 | return nestedVariable; 14 | } 15 | 16 | [[cheerp::jsexport]] 17 | void setNestedVariable(int value) { 18 | nestedVariable = value; 19 | } 20 | } 21 | 22 | int main() { 23 | assertEqual(1, Module::nestedVariable, "CPP: 1 == nestedVariable"); 24 | assertEqual(1, Module::getNestedVariable(), "CPP: 1 == getNestedVariable()"); 25 | Module::nestedVariable = 2; 26 | assertEqual(2, Module::nestedVariable, "CPP: 2 == nestedVariable"); 27 | assertEqual(2, Module::getNestedVariable(), "CPP: 2 == getNestedVariable()"); 28 | Module::setNestedVariable(3); 29 | assertEqual(3, Module::nestedVariable, "CPP: 3 == nestedVariable"); 30 | assertEqual(3, Module::getNestedVariable(), "CPP: 3 == getNestedVariable()"); 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/jsexport/nested_variables.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | assert(3 == _.Module.nestedVariable, "JS: 3 == nestedVariable"); 4 | assert(3 == _.Module.getNestedVariable(), "JS: 3 == getNestedVariable()"); 5 | _.Module.nestedVariable = 4; 6 | assert(4 == _.Module.nestedVariable, "JS: 4 == nestedVariable"); 7 | assert(4 == _.Module.getNestedVariable(), "JS: 4 == getNestedVariable()"); 8 | _.Module.setNestedVariable(5); 9 | assert(5 == _.Module.nestedVariable, "JS: 5 == nestedVariable"); 10 | assert(5 == _.Module.getNestedVariable(), "JS: 5 == getNestedVariable()"); 11 | } 12 | function assert(condition, message) 13 | { 14 | console.log(message, condition ? "SUCCESS" : "FAILURE"); 15 | } 16 | function getPromise(_) 17 | { 18 | return _.Module.getNestedVariable.promise; 19 | } 20 | function getExports() 21 | { 22 | return { 23 | get Module() { 24 | return Module; 25 | } 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/jsexport/parameters_client.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2020 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | [[cheerp::jsexport]][[cheerp::genericjs]] 8 | client::String* concatenateStrings(const client::String& a, const client::String& b) 9 | { 10 | return a.concat(b); 11 | } 12 | 13 | 14 | [[cheerp::genericjs]] 15 | void webMain() 16 | { 17 | client::String* S; 18 | __asm__("concatenateStrings('Hello', ' World')" : "=r"(S) :); 19 | 20 | std::string cpp_string = (std::string)(*S); 21 | assertEqual(cpp_string.c_str(), "Hello World", "JSExport with client paramethers and return"); 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/jsexport/qualifiers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // No asserts here, just make sure it compiles. 4 | 5 | [[cheerp::jsexport]] [[cheerp::genericjs]] 6 | void foo(const int, const client::String&, const client::String*) {} 7 | -------------------------------------------------------------------------------- /tests/unit/jsexport/static_variables.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2024 Leaning Technologies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | struct [[cheerp::jsexport]] Struct { 7 | [[cheerp::jsexport]] 8 | static int staticVariable; 9 | 10 | static int getStaticVariable() { 11 | return staticVariable; 12 | } 13 | 14 | static void setStaticVariable(int value) { 15 | staticVariable = value; 16 | } 17 | }; 18 | 19 | int Struct::staticVariable = 1; 20 | 21 | int main() { 22 | assertEqual(1, Struct::staticVariable, "CPP: 1 == staticVariable"); 23 | assertEqual(1, Struct::getStaticVariable(), "CPP: 1 == getStaticVariable()"); 24 | Struct::staticVariable = 2; 25 | assertEqual(2, Struct::staticVariable, "CPP: 2 == staticVariable"); 26 | assertEqual(2, Struct::getStaticVariable(), "CPP: 2 == getStaticVariable()"); 27 | Struct::setStaticVariable(3); 28 | assertEqual(3, Struct::staticVariable, "CPP: 3 == staticVariable"); 29 | assertEqual(3, Struct::getStaticVariable(), "CPP: 3 == getStaticVariable()"); 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/jsexport/static_variables.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | assert(3 == _.Struct.staticVariable, "JS: 3 == staticVariable"); 4 | assert(3 == _.Struct.getStaticVariable(), "JS: 3 == getStaticVariable()"); 5 | _.Struct.staticVariable = 4; 6 | assert(4 == _.Struct.staticVariable, "JS: 4 == staticVariable"); 7 | assert(4 == _.Struct.getStaticVariable(), "JS: 4 == getStaticVariable()"); 8 | _.Struct.setStaticVariable(5); 9 | assert(5 == _.Struct.staticVariable, "JS: 5 == staticVariable"); 10 | assert(5 == _.Struct.getStaticVariable(), "JS: 5 == getStaticVariable()"); 11 | } 12 | function assert(condition, message) 13 | { 14 | console.log(message, condition ? "SUCCESS" : "FAILURE"); 15 | } 16 | function getPromise(_) 17 | { 18 | return _.Struct.promise; 19 | } 20 | function getExports() 21 | { 22 | return { 23 | get Struct() { 24 | return Struct; 25 | } 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/jsexport/unsafe_clang.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | [[cheerp::jsexport_unsafe]] 4 | uint32_t doSomethin2g(uint32_t a) 5 | { 6 | return a*a; 7 | } 8 | -------------------------------------------------------------------------------- /tests/unit/jsexport/unsafe_gnu.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | __attribute__((cheerp_jsexport_unsafe)) 4 | uint32_t 5 | doSomething(uint32_t a) 6 | { 7 | return a*a; 8 | } 9 | -------------------------------------------------------------------------------- /tests/unit/memory/arraynew.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | static int constructionCount; 11 | static int destructionCount; 12 | int a; 13 | A():a(42) 14 | { 15 | constructionCount++; 16 | } 17 | ~A() 18 | { 19 | destructionCount++; 20 | } 21 | }; 22 | 23 | int A::constructionCount = 0; 24 | int A::destructionCount = 0; 25 | 26 | void webMain() 27 | { 28 | A* a = new A[10]; 29 | delete[] a; 30 | assertEqual(A::constructionCount, 10, "Array new support 1/2"); 31 | assertEqual(A::destructionCount, 10, "Array new support 2/2"); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /tests/unit/memory/kinds.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | //Check pointer kinds assigned by Cheerp 10 | client::String* str = new client::String(); 11 | assertEqual(__builtin_cheerp_pointer_kind(str), /*COMPLETE_OBJECY*/0u, "Pointer kind on client object"); 12 | 13 | std::string* str2 = new std::string("text"); 14 | assertEqual(__builtin_cheerp_pointer_kind(str2), /*COMPLETE_OBJECY*/0u, "Pointer kind on heap allocated object"); 15 | delete str2; 16 | 17 | union u 18 | { 19 | int i; 20 | float f; 21 | }; 22 | 23 | u* blData = new u(); 24 | blData->i = 0x41400000; 25 | assertEqual(blData->f, 12.0f, "Pointer kind on union 1/2"); 26 | assertEqual(__builtin_cheerp_pointer_kind(blData), /*BYTE_LAYOUT*/3u, "Pointer kind on union 2/2"); 27 | delete blData; 28 | 29 | int a[] = {1,2,3,4,5,6,7,8}; 30 | 31 | int* ap = a+2; 32 | 33 | assertEqual(__builtin_cheerp_pointer_kind(ap), /*SPLIT_REGULAR*/1u, "Pointer kind on array"); 34 | assertEqual(*ap, 3, "Force array loads"); 35 | } 36 | -------------------------------------------------------------------------------- /tests/unit/memory/multiarray.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | static volatile int constructionCount; 11 | int a; 12 | A():a(42) 13 | { 14 | constructionCount++; 15 | } 16 | }; 17 | 18 | volatile int A::constructionCount = 0; 19 | 20 | void webMain() 21 | { 22 | volatile int a[3][4]; 23 | for(int i=0;i<12;i++) 24 | a[i / 4][i % 4] = i; 25 | int aTotal = 0; 26 | for(int i=0;i<12;i++) 27 | aTotal += a[i / 4][i % 4]; 28 | assertEqual(aTotal, 66, "Multiarray support 1/"); 29 | volatile int(*b)[4] = new int[3][4]; 30 | for(int i=0;i<12;i++) 31 | b[i / 4][i % 4] = i; 32 | int bTotal = 0; 33 | for(int i=0;i<12;i++) 34 | bTotal += b[i / 4][i % 4]; 35 | assertEqual(bTotal, 66, "Multiarray support 2/"); 36 | A c[3][4]; 37 | assertEqual(int(A::constructionCount), 12, "Multiarray support 3/"); 38 | A (*d)[4] = new A[3][4]; 39 | assertEqual(int(A::constructionCount), 24, "Multiarray support 4/"); 40 | } 41 | -------------------------------------------------------------------------------- /tests/unit/memory/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | class A 9 | { 10 | public: 11 | int a; 12 | int b; 13 | A(int x):a(x),b(x) 14 | { 15 | } 16 | }; 17 | 18 | void webMain() 19 | { 20 | //Test arrays of native types 21 | int a[] = {1,2,3,4,5,6,7,8}; 22 | int b[] = {1,2,3,4,5,6,7,8}; 23 | int c[] = {0,0,0,0,0,0,0,0}; 24 | 25 | memmove(c,a,8*sizeof(int)); 26 | assertEqual(c[3], 4, "Memmove, (native types) on isolated memory"); 27 | 28 | memmove(a+2,a,6*sizeof(int)); 29 | assertEqual(a[3], 2, "Memmove, (native types) destination after source"); 30 | 31 | memmove(b,b+2,6*sizeof(int)); 32 | assertEqual(b[3], 6, "Memmove, (native types) destination before source"); 33 | 34 | //Test arrays of objects 35 | A oa[] = {9,10,11,12,13,14,15,16}; 36 | A ob[] = {9,10,11,12,13,14,15,16}; 37 | A oc[] = {0,0,0,0,0,0,0,0}; 38 | 39 | memmove(oc,oa,8*sizeof(A)); 40 | assertEqual(oc[3].b, 12, "Memmove, (object types) on isolated memory"); 41 | 42 | memmove(oa+2,oa,6*sizeof(A)); 43 | assertEqual(oa[3].b, 10, "Memmove, (object types) destination after source"); 44 | 45 | memmove(ob,ob+2,6*sizeof(A)); 46 | assertEqual(ob[3].b, 14, "Memmove, (object types) destination before source"); 47 | 48 | //Test sparse arrays of native types 49 | float sa[9] = {0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0}; 50 | float* volatile psa = &sa[4]; 51 | assertEqual(*psa, -1.0, 1e-6, "Accessing sparse arrays"); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /tests/unit/memory/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | //Test pointer arithmetic 10 | int a[6] = { 1, 2, 3, 4, 5, 6}; 11 | 12 | int* volatile a1=&a[1]; 13 | int* volatile a2=&a[5]; 14 | assertEqual(a2-a1, 4L, "Pointer subtraction"); 15 | 16 | int* volatile a3=a+2; 17 | assertEqual(*a3, 3, "Pointer addition"); 18 | } 19 | -------------------------------------------------------------------------------- /tests/unit/memory/test4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013-2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int a; 10 | float b; 11 | virtual void f() 12 | { 13 | } 14 | A(int x, float y):a(x),b(y) 15 | { 16 | } 17 | }; 18 | 19 | void webMain() 20 | { 21 | //Test copy constructor, it must not use memcpy 22 | A a1(10, 0.2); 23 | A a2(0,0); 24 | 25 | assertEqual(a2.a, 0, "C++ implicit operator=() 1/4"); 26 | assertEqual(a2.b, 0.f, "C++ implicit operator=() 2/4"); 27 | a2 = a1; 28 | assertEqual(a2.a, 10, "C++ implicit operator=() 3/4"); 29 | assertEqual(a2.b, 0.2f, "C++ implicit operator=() 4/4"); 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/memory/test5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int a; 10 | }; 11 | 12 | void webMain() 13 | { 14 | //Test copy constructor, it must not use memcpy 15 | A a1; 16 | a1.a = 42; 17 | 18 | volatile int count = 1; 19 | int* base = &a1.a; 20 | for(int i=0;i 6 | #include 7 | 8 | void webMain() 9 | { 10 | //Test placement new 11 | int a; 12 | new (&a) int(42); 13 | assertEqual(a, 42, "Placement new"); 14 | //This should cause an error 15 | //new ((void*)&a) int(42); 16 | } 17 | -------------------------------------------------------------------------------- /tests/unit/memory/test7.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014-2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | int a; 11 | A():a(42) 12 | { 13 | } 14 | }; 15 | 16 | void webMain() 17 | { 18 | //Test new on classes 19 | A* a=new A; 20 | assertEqual(a->a, 42, "New on class types 1/2"); 21 | A* a2=new (std::nothrow) A; 22 | assertEqual(a->a, 42, "Nothrow new on class types 2/2"); 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/memory/test8.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | int a; 11 | A(int _a):a(_a) 12 | { 13 | } 14 | }; 15 | 16 | void webMain() 17 | { 18 | //Test new with [[cheerp::nonit]] 19 | //Note that A has no default constructor 20 | A* a=new A[2] [[cheerp::noinit]]; 21 | a[1].a = 42; 22 | assertEqual(a[1].a, 42, "New array with [[cheerp::noinit]]"); 23 | A(*a2)[3]=new A[2][3] [[cheerp::noinit]]; 24 | a2[1][1].a = 43; 25 | assertEqual(a2[1][1].a, 43, "New multi array with [[cheerp::noinit]]"); 26 | A* a3=new A [[cheerp::noinit]]; 27 | a3->a = 44; 28 | assertEqual(a3->a, 44, "New with [[cheerp::noinit]]"); 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/memory/typed_memintrinsics.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technologies 3 | //===---------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | template 9 | void testTemplatedMemIntrinsics(); 10 | 11 | void webMain() 12 | { 13 | int a[] = {1,2,3,4,5,6,7,8}; 14 | unsigned b[] = {0,0,0,0,0,0,0,0}; 15 | unsigned c[] = {0,0,0,0,0,0,0,0}; 16 | 17 | memmove(b, a, 8 * sizeof(int)); 18 | assertEqual(b[3], 4, "Memmove on signed and unsigned types"); 19 | 20 | memcpy(c, a, 8 * sizeof(int)); 21 | assertEqual(c[3], 4, "Memcpy on signed and unsigned types"); 22 | 23 | testTemplatedMemIntrinsics(); 24 | } 25 | 26 | template 27 | void testTemplatedMemIntrinsics() { 28 | A a[] = {1,2,3,4,5,6,7,8}; 29 | B b[] = {0,0,0,0,0,0,0,0}; 30 | B c[] = {0,0,0,0,0,0,0,0}; 31 | 32 | memmove(b, a, 8 * sizeof(A)); 33 | assertEqual(b[3], 4, "Memmove on template types"); 34 | 35 | memcpy(c, a, 8 * sizeof(A)); 36 | assertEqual(c[3], 4, "Memcpy on template types"); 37 | } 38 | -------------------------------------------------------------------------------- /tests/unit/memory/typedarrays_operator.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | client::Int8Array* a = new client::Int8Array(10); 11 | client::Int8Array& r = *a; 12 | r[3] = 42; 13 | assertEqual(r[0], (char)0, "Operator[] on typed arrays 1/2"); 14 | assertEqual(r[3], (char)42, "Operator[] on typed arrays 2/2"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/static/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | int a; 11 | A():a(42) 12 | { 13 | assertEqual(true, true, "Static initialiation of class instances 1/3"); 14 | } 15 | }; 16 | 17 | int f() 18 | { 19 | static A a; 20 | a.a++; 21 | return a.a; 22 | } 23 | 24 | void webMain() 25 | { 26 | assertEqual(f(), 43, "Static initialiation of class instances 2/3"); 27 | assertEqual(f(), 44, "Static initialiation of class instances 3/3"); 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/std/chrono.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); 11 | std::chrono::high_resolution_clock::time_point t2 = t1+std::chrono::high_resolution_clock::duration(1); 12 | assertEqual((t2-t1).count(), 1LL, "std::chrono"); 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/std/gettimeofday.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void webMain() 10 | { 11 | timeval tv; 12 | struct timezone tz; 13 | int ret=gettimeofday(&tv, &tz); 14 | assertEqual(ret, 0, "gettimeofday 1/3"); 15 | assertEqual(tv.tv_sec!=0, true, "gettimeofday 2/3"); 16 | assertEqual(tv.tv_usec!=0, true, "gettimeofday 3/3"); 17 | volatile time_t t1; 18 | time_t t2; 19 | t1=time(&t2); 20 | assertEqual((time_t)t1,t2, "time"); 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/std/locale.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | #include 8 | 9 | void webMain() 10 | { 11 | const char* loc; 12 | loc = setlocale(LC_ALL,"C"); 13 | assertEqual(loc, "C", "setlocale 1/4"); 14 | 15 | loc = setlocale(LC_ALL,"C.UTF-8"); 16 | assertEqual(loc, "C.UTF-8;C;C;C;C;C", "setlocale 2/4"); 17 | 18 | // Go back to default ("C.UTF-8") 19 | loc = setlocale(LC_ALL,""); 20 | assertEqual(loc, "C.UTF-8;C;C;C;C;C", "setlocale 3/4"); 21 | 22 | // Invalid locale 23 | loc = setlocale(LC_ALL,"GARBAGE"); 24 | assertEqual(loc, "GARBAGE", "setlocale 4/4"); 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/std/mapdestruction.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | struct A 10 | { 11 | ~A() 12 | { 13 | destructionCount++; 14 | } 15 | static int destructionCount; 16 | }; 17 | 18 | int A::destructionCount = 0; 19 | 20 | void webMain() 21 | { 22 | std::map m1; 23 | m1[1]; 24 | m1.clear(); 25 | assertEqual(A::destructionCount, 1, "Destructors in std::map 1/2"); 26 | std::unordered_map m2; 27 | m2[1]; 28 | m2.clear(); 29 | assertEqual(A::destructionCount, 2, "Destructors in std::map 2/2"); 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/std/memcmp.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void webMain() 10 | { 11 | int a = 42; 12 | int b = 41; 13 | #ifdef __ASMJS__ 14 | assertEqual(memcmp(&a,&b,sizeof(int)), 1, "memcmp (asmjs/wasm) 1/2"); 15 | #endif 16 | assertEqual(cheerp::memcmp(&a,&b,sizeof(int)), 1, "memcmp (safe) 1/2"); 17 | b++; 18 | #ifdef __ASMJS__ 19 | assertEqual(memcmp(&a,&b,sizeof(int)), 0, "memcmp (asmjs/wasm) 2/2"); 20 | #endif 21 | assertEqual(cheerp::memcmp(&a,&b,sizeof(int)), 0, "memcmp (safe) 2/2"); 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/std/sort.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | struct S 11 | { 12 | int32_t i; 13 | std::string s; 14 | bool operator<(const S& r) const 15 | { 16 | return this->i < r.i; 17 | } 18 | }; 19 | 20 | std::vector v; 21 | 22 | void webMain() 23 | { 24 | std::sort(v.begin(),v.end()); 25 | assertEqual(v.size(), 0u, "std::sort on complex structures"); 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/std/sscanf.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | std::string test = "padding=1,2,3,4"; 11 | int a,b,c,d; 12 | sscanf(test.c_str(), "padding=%d,%d,%d,%d", &a, &b, &c, &d); 13 | assertEqual(a, 1, "sscanf 1/4"); 14 | assertEqual(b, 2, "sscanf 2/4"); 15 | assertEqual(c, 3, "sscanf 3/4"); 16 | assertEqual(d, 4, "sscanf 4/4"); 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/std/stdmemfuncs.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 10 | int b[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 11 | std::uninitialized_copy(&a[0], &a[7], &b[0]); 12 | assertEqual(b[6], 6, "std::uninitialized_copy 1/2"); 13 | assertEqual(b[7], 0, "std::uninitialized_copy 2/2"); 14 | 15 | std::uninitialized_fill(&b[0], &b[7], 42); 16 | assertEqual(b[6], 42, "std::uninitialized_fill 1/2"); 17 | assertEqual(b[7], 0, "std::uninitialized_fill 2/2"); 18 | 19 | std::uninitialized_fill_n(&b[0], 7, 43); 20 | assertEqual(b[6], 43, "std::uninitialized_fill_n 1/2"); 21 | assertEqual(b[7], 0, "std::uninitialized_fill_n 2/2"); 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/std/stringassign.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2017 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | { 11 | std::string str1; 12 | str1.reserve(3); 13 | std::string str2; 14 | str2.push_back('1'); 15 | str2.push_back('2'); 16 | str2.push_back('5'); 17 | str1 = str2; 18 | assertEqual(str1, str2, "std::string::assign"); 19 | } 20 | { 21 | std::u16string str1; 22 | str1.reserve(3); 23 | std::u16string str2; 24 | str2.push_back('1'); 25 | str2.push_back('2'); 26 | str2.push_back('5'); 27 | str1 = str2; 28 | assertEqual(str1, str2, "std::u16string::assign"); 29 | } 30 | { 31 | std::string str1; 32 | str1 = 32; 33 | assertEqual(str1, std::string(" "), "std::string::assign from char 1/3"); 34 | str1 = "A"; 35 | str1 = 32; 36 | assertEqual(str1, std::string(" "), "std::string::assign from char 2/3"); 37 | str1 = "AB"; 38 | str1 = 32; 39 | assertEqual(str1, std::string(" "), "std::string::assign from char 3/3"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/std/stringhashing.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void testUnorderedSetOfString() 10 | { 11 | std::unordered_set a; 12 | assertEqual(a.size(), 0u, "std::set 1/4"); 13 | a.insert("1"); 14 | assertEqual(a.size(), 1u, "std::set 2/4"); 15 | a.insert("10"); 16 | a.insert("99"); 17 | a.insert("100"); 18 | a.insert("100"); 19 | a.insert("-2"); 20 | assertEqual(a.size(), 5u, "std::set 3/4"); 21 | const char* expected[] = {"-2", "99", "100", "10", "1"}; 22 | std::unordered_set::iterator it = a.begin(); 23 | bool correctOrder = true; 24 | for(int i=0;i ordering 4/4"); 31 | } 32 | 33 | void testUnorderedSetOfWString() 34 | { 35 | std::unordered_set a; 36 | assertEqual(a.size(), 0u, "std::set 1/4"); 37 | a.insert(L"1"); 38 | assertEqual(a.size(), 1u, "std::set 2/4"); 39 | a.insert(L"10"); 40 | a.insert(L"99"); 41 | a.insert(L"100"); 42 | a.insert(L"100"); 43 | a.insert(L"-2"); 44 | assertEqual(a.size(), 5u, "std::set 3/4"); 45 | const wchar_t* expected[] = {L"100", L"-2", L"99", L"10", L"1"}; 46 | std::unordered_set::iterator it = a.begin(); 47 | bool correctOrder = true; 48 | for(int i=0;i ordering 4/4"); 55 | } 56 | 57 | void webMain() 58 | { 59 | testUnorderedSetOfString(); 60 | testUnorderedSetOfWString(); 61 | } 62 | -------------------------------------------------------------------------------- /tests/unit/std/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | namespace { 9 | 10 | struct Point 11 | { 12 | int x; 13 | int y; 14 | }; 15 | 16 | }; 17 | 18 | void webMain() 19 | { 20 | std::list l; 21 | assertEqual(l.size(), 0u, "List construction"); 22 | l.insert(l.begin(),Point{.x=1,.y=2}); 23 | assertEqual(l.size(), 1u, "List insert"); 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/std/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | int func() 9 | { 10 | return 42; 11 | } 12 | 13 | void webMain() 14 | { 15 | std::function f=func; 16 | assertEqual(f(), 42, "Function object"); 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/std/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013,2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | std::string str; 11 | assertEqual(str.size(), 0u, "String empty construction 1/2"); 12 | assertEqual(str.capacity(), 0u, "String empty construction 2/2"); 13 | std::string str2("test"); 14 | assertEqual(str2.size(), 4u, "String construction 1/2"); 15 | assertEqual(str2.capacity(), 15u, "String construction 2/2"); 16 | str2.insert(0, "pre", 3); 17 | assertEqual(str2, std::string("pretest"), "String insertion 1/2"); 18 | str2.insert(0, str2.data()+3, 4); 19 | assertEqual(str2, std::string("testpretest"), "String insertion 2/2"); 20 | std::string a("BBBBB-CCC-"); 21 | a.append("AAAAAA",6); 22 | assertEqual(a, std::string("BBBBB-CCC-AAAAAA"), "String concatenation"); 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/std/test4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | void webMain() 10 | { 11 | #ifndef PRE_EXECUTE_TEST 12 | //iostream and sstream test 13 | std::cout << "Cout output : SUCCESS" << std::endl; 14 | std::cerr << "Cerr output : SUCCESS" << std::endl; 15 | #endif 16 | std::ostringstream str; 17 | str << "test " << 42; 18 | assertEqual(str.str().c_str(), "test 42", "stringstream 1/2"); 19 | // Input/Output string stream 20 | std::stringstream str2; 21 | str2 << "43"; 22 | int res; 23 | str2 >> res; 24 | assertEqual(res, 43, "stringstream 2/2"); 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/std/test5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | #include 8 | //Including this should cause an error 9 | //#include 10 | 11 | void webMain() 12 | { 13 | //Test mutex 14 | std::mutex m; 15 | m.lock(); 16 | m.unlock(); 17 | assertEqual(true, true, "Fake mutex support"); 18 | //Test atomic 19 | std::atomic a(1); 20 | a++; 21 | a--; 22 | ++a; 23 | assertEqual(a.load(), 2, "Fake atomic support"); 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/std/test6.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | void webMain() 11 | { 12 | struct A 13 | { 14 | list v; 15 | int a,b; 16 | } obj; 17 | 18 | list l; 19 | 20 | l.push_back(move(obj)); 21 | assertEqual(l.size(), 1u, "List push_back 1/2"); 22 | l.push_back(obj); 23 | assertEqual(l.size(), 2u, "List push_back 2/2"); 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/std/test9.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | std::vector v; 11 | for(int i=0;i<10;i++) 12 | v.push_back(i); 13 | assertEqual(v.end()-v.begin(), 10L, "std::vector 1/1"); 14 | v.erase(v.begin()+3); 15 | assertEqual(v.end()-v.begin(), 9L, "std::vector 2/2"); 16 | } 17 | -------------------------------------------------------------------------------- /tests/unit/std/tostring.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2016 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | void webMain() 9 | { 10 | std::string val = std::to_string(40.0f); 11 | assertEqual(val, "40.000000", "std::to_string for floats"); 12 | } 13 | -------------------------------------------------------------------------------- /tests/unit/test1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct B 4 | { 5 | int b; 6 | }; 7 | 8 | struct A 9 | { 10 | B b; 11 | int a; 12 | }; 13 | 14 | A a2; 15 | 16 | void webMain() 17 | { 18 | A a; 19 | memcpy(&a.b,&a2.b,sizeof(B)); 20 | volatile int u=a.b.b; 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/test4.cpp: -------------------------------------------------------------------------------- 1 | //#include 2 | 3 | struct B 4 | { 5 | int b; 6 | B():b(1){} 7 | virtual B* clone() = 0; 8 | }; 9 | 10 | struct A: public B 11 | { 12 | int a; 13 | A():a(2){} 14 | A* clone() { return new A(*this); } 15 | }; 16 | 17 | void webMain() 18 | { 19 | A a; 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/tests.h: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #ifndef _CHEERP_TESTS_H 6 | #define _CHEERP_TESTS_H 7 | 8 | #include 9 | #include 10 | 11 | extern "C" void assertEqualImpl(bool success, const char* msg) 12 | #ifdef PRE_EXECUTE_TEST 13 | ; 14 | #else 15 | { 16 | if (success) { 17 | cheerp::console_log(msg, ": SUCCESS"); 18 | } else { 19 | cheerp::console_log(msg, ": FAILURE"); 20 | } 21 | } 22 | #endif 23 | 24 | void assertEqual(double value, double expected, double epsilon, const char* msg) 25 | { 26 | assertEqualImpl(value >= expected - epsilon && value <= expected + epsilon, msg); 27 | } 28 | 29 | void assertEqual(const char *value, const char *expected, const char* msg) 30 | { 31 | assertEqualImpl(strcmp(value, expected) == 0, msg); 32 | } 33 | 34 | template 35 | void assertEqual(const T value, const T expected, const char* msg) 36 | { 37 | assertEqualImpl(value==expected, msg); 38 | } 39 | 40 | template 41 | [[clang::optnone]] 42 | T unitBlackBox(T v) 43 | { 44 | static T a[1]; 45 | volatile T* volatile p = &a[0]; 46 | a[0] = v; 47 | v = *p; 48 | return v; 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct structWithAtomicMember 5 | { 6 | std::atomic atomicValue; 7 | }; 8 | 9 | struct normalStruct 10 | { 11 | int value; 12 | }; 13 | 14 | int main() 15 | { 16 | std::atomic val = 4205; 17 | val.fetch_add(1391); 18 | val.fetch_and(6234); 19 | val.fetch_or(9196); 20 | val.fetch_sub(4985); 21 | val.fetch_xor(7578); 22 | assertEqual(val.load(), 15641, "Atomic binary operations"); 23 | 24 | int b = 90; 25 | b += val.exchange(3125); 26 | b += val.fetch_add(7264); 27 | b += val.fetch_sub(4981); 28 | b += val.fetch_or(2037); 29 | b += val.fetch_and(8185); 30 | b += val.load(); 31 | assertEqual(b, 46915 , "Atomic binary return values"); 32 | 33 | structWithAtomicMember s1; 34 | s1.atomicValue.store(3); 35 | s1.atomicValue.fetch_add(95); 36 | s1.atomicValue.fetch_and(51); 37 | assertEqual(s1.atomicValue.load(), 34, "Atomic value inside struct"); 38 | 39 | normalStruct s2 = {3}; 40 | std::atomic s3; 41 | s3.store(s2); 42 | s2.value = 25; 43 | s2 = s3.load(); 44 | assertEqual(s2.value, 3, "Atomic struct"); 45 | } 46 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic1.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation() { 2 | } 3 | function getPromise(_) 4 | { 5 | return Promise.resolve(); 6 | } 7 | function getExports() 8 | { 9 | return {}; 10 | } 11 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node 5 | { 6 | int value; 7 | Node* next; 8 | }; 9 | std::atomic listHead(nullptr); 10 | 11 | void appendToList(int newValue) 12 | { 13 | Node* oldHead = listHead; 14 | Node* newNode = new Node {newValue, oldHead}; 15 | 16 | while (!listHead.compare_exchange_strong(oldHead, newNode)) 17 | newNode->next = oldHead; 18 | } 19 | 20 | int main() 21 | { 22 | for (int i = 0; i < 10; i++) 23 | appendToList(i); 24 | 25 | Node* it = listHead; 26 | it = it->next->next->next; 27 | assertEqual(it->value, 6, "Compare exchange list"); 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic2.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation() { 2 | } 3 | function getPromise(_) 4 | { 5 | return Promise.resolve(); 6 | } 7 | function getExports() 8 | { 9 | return {}; 10 | } 11 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::atomic value(0); 5 | 6 | void addToNumber() 7 | { 8 | int num = value.load(); 9 | int newNum = num + 1; 10 | while (!value.compare_exchange_weak(num, newNum)) 11 | newNum = num + 1; 12 | } 13 | 14 | int main() 15 | { 16 | for (int i = 0; i < 100; i++) 17 | addToNumber(); 18 | assertEqual(value.load(), 100, "Simple compare exchange"); 19 | } 20 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic3.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation() { 2 | } 3 | function getPromise(_) 4 | { 5 | return Promise.resolve(); 6 | } 7 | function getExports() 8 | { 9 | return {}; 10 | } 11 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic4.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation() { 2 | } 3 | function getPromise(_) 4 | { 5 | return Promise.resolve(); 6 | } 7 | function getExports() 8 | { 9 | return {}; 10 | } 11 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic_lowering1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct structWithAtomicMember 5 | { 6 | std::atomic atomicValue; 7 | }; 8 | 9 | struct normalStruct 10 | { 11 | int value; 12 | }; 13 | 14 | int main() 15 | { 16 | std::atomic val = 4205; 17 | val.fetch_add(1391); 18 | val.fetch_and(6234); 19 | val.fetch_or(9196); 20 | val.fetch_sub(4985); 21 | val.fetch_xor(7578); 22 | assertEqual(val.load(), 15641, "Atomic binary operations"); 23 | 24 | int b = 90; 25 | b += val.exchange(3125); 26 | b += val.fetch_add(7264); 27 | b += val.fetch_sub(4981); 28 | b += val.fetch_or(2037); 29 | b += val.fetch_and(8185); 30 | b += val.load(); 31 | assertEqual(b, 46915 , "Atomic binary return values"); 32 | 33 | structWithAtomicMember s1; 34 | s1.atomicValue.store(3); 35 | s1.atomicValue.fetch_add(95); 36 | s1.atomicValue.fetch_and(51); 37 | assertEqual(s1.atomicValue.load(), 34, "Atomic value inside struct"); 38 | 39 | normalStruct s2 = {3}; 40 | std::atomic s3; 41 | s3.store(s2); 42 | s2.value = 25; 43 | s2 = s3.load(); 44 | assertEqual(s2.value, 3, "Atomic struct"); 45 | } 46 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic_lowering2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Node 5 | { 6 | int value; 7 | Node* next; 8 | }; 9 | std::atomic listHead(nullptr); 10 | 11 | void appendToList(int newValue) 12 | { 13 | Node* oldHead = listHead; 14 | Node* newNode = new Node {newValue, oldHead}; 15 | 16 | while (!listHead.compare_exchange_strong(oldHead, newNode)) 17 | newNode->next = oldHead; 18 | } 19 | 20 | int main() 21 | { 22 | for (int i = 0; i < 10; i++) 23 | appendToList(i); 24 | 25 | Node* it = listHead; 26 | it = it->next->next->next; 27 | assertEqual(it->value, 6, "Compare exchange list"); 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/threading/atomic_lowering3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::atomic value(0); 5 | 6 | void addToNumber() 7 | { 8 | int num = value.load(); 9 | int newNum = num + 1; 10 | while (!value.compare_exchange_weak(num, newNum)) 11 | newNum = num + 1; 12 | } 13 | 14 | int main() 15 | { 16 | for (int i = 0; i < 100; i++) 17 | addToNumber(); 18 | assertEqual(value.load(), 100, "Simple compare exchange"); 19 | } 20 | -------------------------------------------------------------------------------- /tests/unit/threading/thread_setup.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int testGlobal = 0; 4 | 5 | [[cheerp::jsexport]] 6 | int doCalculation(int amount) 7 | { 8 | return amount * testGlobal; 9 | } 10 | 11 | void webMain() 12 | { 13 | testGlobal = 5; 14 | } 15 | -------------------------------------------------------------------------------- /tests/unit/threading/thread_setup.testing.js: -------------------------------------------------------------------------------- 1 | function onInstantiation(_) 2 | { 3 | var result = _.doCalculation(5); 4 | var condition = result == 25; 5 | console.log("Module returned after thread setup :", condition ? "SUCCESS" : "FAILURE"); 6 | } 7 | function getPromise(_) 8 | { 9 | return _.doCalculation.promise; 10 | } 11 | function getExports() 12 | { 13 | return { 14 | get doCalculation() { 15 | return doCalculation; 16 | }, 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /tests/unit/types/cinheritance.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct BaseStruct 8 | { 9 | int a; 10 | float b; 11 | }; 12 | 13 | struct DerivedStruct 14 | { 15 | BaseStruct base; 16 | int c; 17 | }; 18 | 19 | struct DerivedStruct2 20 | { 21 | DerivedStruct2():base({2,4}),c(5) 22 | { 23 | } 24 | BaseStruct base; 25 | int c; 26 | }; 27 | 28 | DerivedStruct2 gd2; 29 | 30 | void webMain() 31 | { 32 | //Test merging of the first struct member into the class 33 | //this is useful to support C-style polymorphism 34 | DerivedStruct s = { { 1, 2.5f }, 2 }; 35 | DerivedStruct* volatile d = &s; 36 | 37 | assertEqual(d->base.a, 1, "C-style polymorphism 1/5"); 38 | assertEqual(d->base.b, 2.5f, "C-style polymorphism 2/5"); 39 | assertEqual(d->c, 2, "C-style polymorphism 3/5"); 40 | 41 | BaseStruct* volatile b = (BaseStruct*)d; 42 | assertEqual(b->a, 1, "C-style polymorphism 4/5"); 43 | assertEqual(b->b, 2.5f, "C-style polymorphism 5/5"); 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/types/funccasts.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2019 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | int foo(int a, int b, int c, int d) 11 | { 12 | return a+b+c+d; 13 | } 14 | int bar(int a, int b, int c, int d, int e) 15 | { 16 | return a+b+c+d+e; 17 | } 18 | 19 | typedef int (*fptr)(int, int, int, int, int); 20 | void webMain() 21 | { 22 | fptr f = unitBlackBox(1) ? (fptr)foo : bar; 23 | int r = f(1,2,3,4,5); 24 | assertEqual(r, 10, "FixFunctionCasts 1/1"); 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/types/memberfunctions2.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // Copyright 2019 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int i = 1; 10 | [[clang::optnone]] 11 | int funcA(int a) 12 | { 13 | return i+a; 14 | } 15 | }; 16 | 17 | struct B 18 | { 19 | int j = 2; 20 | }; 21 | 22 | struct C: public B, public A 23 | { 24 | int k = 3; 25 | [[clang::optnone]] 26 | int funcC(int a) 27 | { 28 | return funcA(a+k); 29 | } 30 | }; 31 | 32 | struct D: public C 33 | { 34 | int l = 4; 35 | }; 36 | 37 | typedef int(D::*FPD)(int); 38 | 39 | [[clang::optnone]] 40 | FPD getMemberPointerA() 41 | { 42 | return static_cast(&C::funcA); 43 | } 44 | [[clang::optnone]] 45 | FPD getMemberPointerC() 46 | { 47 | return static_cast(&C::funcC); 48 | } 49 | 50 | [[clang::optnone]] 51 | bool bb(bool b) 52 | { 53 | return b; 54 | } 55 | 56 | [[clang::optnone]] 57 | int baz(A* a) 58 | { 59 | //C* c = static_cast(a); 60 | //return c->k; 61 | return a->i; 62 | } 63 | 64 | int main() 65 | { 66 | D d; 67 | FPD volatile f = bb(false) ? getMemberPointerC() : getMemberPointerA(); 68 | assertEqual((d.*f)(2), 3 , "Cast member function pointer from non primary base 1/1"); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /tests/unit/types/packed.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct __attribute__((packed)) MyStruct{ 8 | char c; 9 | int a; 10 | }; 11 | 12 | int main() 13 | { 14 | assertEqual(sizeof(MyStruct), 5u, "Sizeof support"); 15 | return 0; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /tests/unit/types/padding1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | 9 | class basic_json 10 | { 11 | public: 12 | basic_json() 13 | { 14 | } 15 | 16 | public: 17 | /// the type of the current element 18 | char m_type = 0; 19 | long long m_value = 0; 20 | char x = 8; 21 | }; 22 | 23 | template 24 | void testSize() 25 | { 26 | std::vector v(N); 27 | assertEqual(v.size(), N, "Padding support"); 28 | } 29 | 30 | int main() 31 | { 32 | testSize<1>(); 33 | testSize<2>(); 34 | testSize<3>(); 35 | testSize<57>(); 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /tests/unit/types/padding2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | 9 | struct A 10 | { 11 | public: 12 | A() {} 13 | char m_type = 0; 14 | long long m_value = 0; 15 | }; 16 | 17 | struct B 18 | { 19 | public: 20 | B() {} 21 | char some_char = 2; 22 | A a; 23 | char some_other_char = 23; 24 | A z; 25 | long long some_64 = 123; 26 | }; 27 | 28 | template 29 | void testSize() 30 | { 31 | std::vector v(N); 32 | assertEqual(v.size(), N, "Padding support"); 33 | } 34 | 35 | int main() 36 | { 37 | testSize<1>(); 38 | testSize<2>(); 39 | testSize<3>(); 40 | testSize<57>(); 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /tests/unit/types/padding3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | struct A 9 | { 10 | public: 11 | A() {} 12 | char m_type = 0; 13 | long long m_value = 0; 14 | char XXX = 23; 15 | void addStuff(int X) 16 | { 17 | m_type += X; 18 | m_value *= X; 19 | } 20 | int hash() const 21 | { 22 | return m_value * m_type; 23 | } 24 | }; 25 | 26 | struct B 27 | { 28 | public: 29 | B() {} 30 | char some_char = 2; 31 | A a; 32 | char some_other_char = 23; 33 | A z; 34 | long long some_64 = 123; 35 | void addStuff(int X) 36 | { 37 | some_64 += X; 38 | some_other_char ^= X; 39 | a.addStuff(some_64++); 40 | z.addStuff(some_other_char++); 41 | some_64 += some_other_char; 42 | } 43 | int hash() 44 | { 45 | return a.hash() + z.hash() * some_other_char + some_64; 46 | } 47 | }; 48 | 49 | template 50 | int testSize() 51 | { 52 | std::vector v(N); 53 | for (int i=0; i(); 72 | sum += testSize<2>(); 73 | sum += testSize<3>(); 74 | sum += testSize<57>(); 75 | assertEqual(sum, 29198, "Access to member test"); 76 | return 0; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /tests/unit/types/padding4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | struct A 9 | { 10 | public: 11 | A() {} 12 | char m_type = 0; 13 | long long m_value = 0; 14 | void addStuff(int X) 15 | { 16 | m_type += X; 17 | m_value *= X; 18 | } 19 | int hash() const 20 | { 21 | return m_value * m_type; 22 | } 23 | }; 24 | 25 | struct B 26 | { 27 | public: 28 | B() {} 29 | char some_char = 2; 30 | A a; 31 | void (*someFunc)(int); 32 | A z[12]; 33 | char k; 34 | char some_other_char = 23; 35 | long long some_64 = 123; 36 | char otherChar; 37 | void addStuff(int X) 38 | { 39 | some_64 += X; 40 | some_other_char ^= X; 41 | a.addStuff(some_64++); 42 | z[3].addStuff(some_other_char++); 43 | some_64 += some_other_char; 44 | } 45 | int hash() 46 | { 47 | return a.hash() + z[3].hash() * some_other_char + some_64; 48 | } 49 | }; 50 | 51 | template 52 | int testSize() 53 | { 54 | std::vector v(N); 55 | for (int i=0; i(); 75 | sum += testSize<2>(); 76 | sum += testSize<3>(); 77 | sum += testSize<57>(); 78 | assertEqual(sum, 29198, "Access to member test"); 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /tests/unit/types/padding5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | struct [[cheerp::bytelayout]] A 9 | { 10 | public: 11 | A() {} 12 | char m_type = 0; 13 | long long m_value = 0; 14 | void addStuff(int X) 15 | { 16 | m_type += X; 17 | m_value *= X; 18 | } 19 | int hash() const 20 | { 21 | return m_value * m_type; 22 | } 23 | }; 24 | 25 | struct [[cheerp::bytelayout]] B 26 | { 27 | public: 28 | B() {} 29 | char some_char = 2; 30 | A a; 31 | A z[12]; 32 | char k; 33 | char some_other_char = 23; 34 | long long some_64 = 123; 35 | char lastCHar; 36 | void addStuff(int X) 37 | { 38 | some_64 += X; 39 | some_other_char ^= X; 40 | a.addStuff(some_64++); 41 | z[3].addStuff(some_other_char++); 42 | some_64 += some_other_char; 43 | } 44 | int hash() 45 | { 46 | return a.hash() + z[3].hash() * some_other_char + some_64; 47 | } 48 | }; 49 | 50 | template 51 | [[cheerp::genericjs]] int testSize() 52 | { 53 | B v[N]; 54 | for (int i=0; i(); 72 | sum += testSize<2>(); 73 | sum += testSize<3>(); 74 | sum += testSize<57>(); 75 | assertEqual(sum, 29198, "Access to member test"); 76 | return 0; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /tests/unit/types/padding6.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2021 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | struct __attribute__((packed)) A 9 | { 10 | public: 11 | A() {} 12 | char m_type = 0; 13 | char x; 14 | char r; 15 | char q; 16 | int ad; 17 | long long m_value = 0; 18 | char asd; 19 | void addStuff(int X) 20 | { 21 | m_type += X; 22 | m_value *= X; 23 | } 24 | int hash() const 25 | { 26 | return m_value * m_type; 27 | } 28 | }; 29 | 30 | struct B 31 | { 32 | public: 33 | B() {} 34 | char some_char = 2; 35 | A a; 36 | void (*someFunc)(int); 37 | A z[12]; 38 | char k; 39 | char some_other_char = 23; 40 | long long some_64 = 123; 41 | char otherChar; 42 | void addStuff(int X) 43 | { 44 | some_64 += X; 45 | some_other_char ^= X; 46 | a.addStuff(some_64++); 47 | z[3].addStuff(some_other_char++); 48 | some_64 += some_other_char; 49 | } 50 | int hash() 51 | { 52 | return a.hash() + z[3].hash() * some_other_char + some_64; 53 | } 54 | }; 55 | 56 | template 57 | int testSize() 58 | { 59 | std::vector v(N); 60 | for (int i=0; i(); 79 | sum += testSize<2>(); 80 | sum += testSize<3>(); 81 | sum += testSize<57>(); 82 | assertEqual(sum, 29198, "Access to member test"); 83 | return 0; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /tests/unit/types/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013-2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | //Test objects of type float 10 | float a = 0.2f; 11 | 12 | assertEqual(a, 0.2f, "Float, initialization"); 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/types/test10.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | float data[4][4]; 11 | }; 12 | 13 | void webMain() 14 | { 15 | A a, a2; 16 | a2.data[1][2] = 42; 17 | memcpy(&a,&a2,sizeof(A)); 18 | assertEqual(a.data[1][2], 42.f, "Interaction between arrays of arrays and memory intrinsics"); 19 | } 20 | -------------------------------------------------------------------------------- /tests/unit/types/test11.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct B; 8 | 9 | struct A 10 | { 11 | A* a; 12 | A* (*func)(A*); 13 | }; 14 | 15 | struct B 16 | { 17 | B* b; 18 | A* (*func)(A*); 19 | }; 20 | 21 | A* funcDef(A*) 22 | { 23 | } 24 | 25 | A globalA = { NULL, funcDef }; 26 | 27 | void webMain() 28 | { 29 | A a; 30 | a.a = &a; 31 | volatile B b; 32 | assertEqual(a.a, &a, "Recursive structure uses"); 33 | } 34 | -------------------------------------------------------------------------------- /tests/unit/types/test12.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | union U 8 | { 9 | struct { double x, y, z; }; 10 | double a[3]; 11 | }; 12 | 13 | struct A 14 | { 15 | U u; 16 | }; 17 | 18 | // Partial global initialization to test TypeOptimizer 19 | U globalU = { 42, 43 }; 20 | 21 | void webMain() 22 | { 23 | // Force globalU linking 24 | U* volatile gU = &globalU; 25 | 26 | //Test struct in union 27 | volatile U u; 28 | u.a[0] = 42; 29 | u.a[1] = 43; 30 | u.a[2] = 44; 31 | assertEqual((double)u.x, 42.0, "Struct in unions 1/6"); 32 | assertEqual((double)u.y, 43.0, "Struct in unions 2/6"); 33 | assertEqual((double)u.z, 44.0, "Struct in unions 3/6"); 34 | 35 | volatile A a; 36 | a.u.a[0] = 45; 37 | a.u.a[1] = 46; 38 | a.u.a[2] = 47; 39 | assertEqual((double)a.u.x, 45.0, "Struct in unions 4/6"); 40 | assertEqual((double)a.u.y, 46.0, "Struct in unions 5/6"); 41 | assertEqual((double)a.u.z, 47.0, "Struct in unions 6/6"); 42 | 43 | volatile double* volatile f = &u.a[1]; 44 | assertEqual((double)f[-1], 42.0, "Pointers from arrays in unions 1/3"); 45 | assertEqual((double)f[0], 43.0, "Pointers from arrays in unions 2/3"); 46 | assertEqual((double)f[1], 44.0, "Pointers from arrays in unions 3/3"); 47 | } 48 | -------------------------------------------------------------------------------- /tests/unit/types/test13.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int i; 10 | }; 11 | 12 | struct B 13 | { 14 | int i; 15 | }; 16 | 17 | void webMain() 18 | { 19 | volatile B b = { 2 }; 20 | volatile A a = { 1 }; 21 | volatile void * volatile p = &b.i; 22 | volatile int ai = a.i; 23 | volatile int bi = b.i; 24 | 25 | assertEqual((int)ai, 1, "Pointers to member variables 1/2"); 26 | assertEqual((int)bi, 2, "Pointers to member variables 2/2"); 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/types/test14.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | double a[3]; 10 | void f() __attribute__((noinline)) 11 | { 12 | a[0] = a[1] - a[2]; 13 | a[1] = a[0] + a[1]; 14 | a[2] = a[1] - a[0]; 15 | } 16 | }; 17 | 18 | void webMain() 19 | { 20 | // Test collapsing single elements structs to the element itself 21 | A a; 22 | a.a[0] = 45; 23 | a.a[1] = 46; 24 | a.a[2] = 47; 25 | a.f(); 26 | assertEqual(a.a[0], -1.0, "Collapsing struct to element 1/3"); 27 | assertEqual(a.a[1], 45.0, "Collapsing struct to element 2/3"); 28 | assertEqual(a.a[2], 46.0, "Collapsing struct to element 3/3"); 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/types/test16.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A; 8 | 9 | struct C 10 | { 11 | A* a; 12 | }; 13 | 14 | struct B 15 | { 16 | C c; 17 | }; 18 | 19 | struct A 20 | { 21 | B b; 22 | }; 23 | 24 | void webMain() 25 | { 26 | // Test collapsing of recursive struct 27 | A a; 28 | a.b.c.a = &a; 29 | // Do a cast that is only valid if the struct is collapsed 30 | B* b = reinterpret_cast(&a); 31 | 32 | assertEqual(b->c.a, &a, "Collapsing of recursive structs"); 33 | } 34 | -------------------------------------------------------------------------------- /tests/unit/types/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct S 8 | { 9 | int i; 10 | }; 11 | 12 | struct T 13 | { 14 | float f; 15 | }; 16 | 17 | void webMain() 18 | { 19 | //Test casting to void* 20 | void* volatile opaque1 = (void*)0; 21 | float a = 0.2f; 22 | 23 | opaque1 = &a; 24 | 25 | float* pa = (float*)opaque1; 26 | assertEqual(*pa, 0.2f, "Float, cast to void* and back"); 27 | 28 | S s; 29 | s.i = 42; 30 | opaque1 = &s; 31 | 32 | S* ps = (S*)opaque1; 33 | assertEqual(ps->i, 42, "Structure, cast to void* and back 1/2"); 34 | 35 | T t; 36 | t.f = 42; 37 | opaque1 = &t; 38 | 39 | T* pt = (T*)opaque1; 40 | assertEqual(pt->f, 42.f, "Structure, cast to void* and back 2/2"); 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/types/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | }; 10 | 11 | class B: public A 12 | { 13 | }; 14 | 15 | class C: public B 16 | { 17 | }; 18 | 19 | void webMain() 20 | { 21 | C c; 22 | B* volatile b = &c; 23 | A* volatile a = &c; 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/types/test4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | char a; 11 | }; 12 | 13 | class B: public A 14 | { 15 | public: 16 | int b; 17 | B():b(0xdeadbeaf) 18 | { 19 | a=42; 20 | } 21 | }; 22 | 23 | class C 24 | { 25 | public: 26 | short a; 27 | unsigned int b : 1; 28 | C():a(3),b(1) 29 | { 30 | } 31 | }; 32 | 33 | void webMain() 34 | { 35 | B b; 36 | 37 | assertEqual(b.a, 42, "Alignment at the end of class [1/3]"); 38 | assertEqual(b.b, 0xdeadbeaf, "Alignment at the end of class [2/3]"); 39 | 40 | volatile C c; 41 | assertEqual((short)c.a, (short)3, "Alignment at the end of class [3/3]"); 42 | } 43 | -------------------------------------------------------------------------------- /tests/unit/types/test5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | void webMain() 8 | { 9 | //Test small integer math 10 | volatile unsigned short a=10; 11 | volatile unsigned short b=0xfffe; 12 | assertEqual(b + a, 8, "Int16 unsigned addition"); 13 | assertEqual(b - a, 0xfff4, "Int16 unsigned subtraction"); 14 | assertEqual(b * a, 0xFFEC, "Int16 unsigned multiplication"); 15 | assertEqual(b / a, 0x1999, "Int16 unsigned division"); 16 | assertEqual(b % a, 4, "Int16 unsigned remainder"); 17 | 18 | volatile signed short c=10; 19 | volatile signed short d=0xfffe; 20 | assertEqual(d + c, 8, "Int16 signed addition"); 21 | assertEqual(d - c, -12, "Int16 signed subtraction"); 22 | assertEqual(d * c, -20, "Int16 signed multiplication"); 23 | assertEqual(c / d, -5, "Int16 signed division"); 24 | assertEqual(d % c, -2, "Int16 signed remainder"); 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/types/test6.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | union U 9 | { 10 | int i; 11 | float f; 12 | char a[5]; 13 | }; 14 | 15 | void webMain() 16 | { 17 | //Test union 18 | U u, u2; 19 | u.f = 1234.567; 20 | assertEqual(u.i, 0x449A5225, "Access to unions 1/2"); 21 | assertEqual(u.a[2], 0x9A, "Access to unions 2/2"); 22 | 23 | //Memory ops on unions 24 | memcpy(&u2, &u, sizeof(u)); 25 | assertEqual(u2.i, 0x449A5225, "Memops on unions 1/2"); 26 | memset(&u2, 0, sizeof(u)); 27 | assertEqual(u2.i, 0, "Memops on unions 2/2"); 28 | 29 | // Test arrays of union 30 | U au2[2]; 31 | U* volatile au=au2; 32 | au[1].f = 1234.567; 33 | assertEqual(au[1].i, 0x449A5225, "Access to arrays of unions 1/2"); 34 | au[0].f = 1234.567; 35 | assertEqual(au[0].i, 0x449A5225, "Access to arrays of unions 2/2"); 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/types/test7.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2014 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | bool testSuccessful = false; 8 | bool testSuccessful2 = false; 9 | 10 | class [[cheerp::jsexport]] JsStruct 11 | { 12 | private: 13 | float a; 14 | int b; 15 | public: 16 | JsStruct(float _a, int _b):a(_a),b(_b) 17 | { 18 | } 19 | void test() 20 | { 21 | if(b == 42) 22 | testSuccessful = true; 23 | } 24 | }; 25 | 26 | class [[cheerp::jsexport]] JsStruct2 27 | { 28 | private: 29 | float a; 30 | int b; 31 | public: 32 | JsStruct2() = default; 33 | void set_b(int i) 34 | { 35 | b = i; 36 | } 37 | void test() 38 | { 39 | if(b == 43) 40 | testSuccessful2 = true; 41 | } 42 | float testptr(client::Float32Array* b, int o) 43 | { 44 | float* f = __builtin_cheerp_make_regular(b, o); 45 | return f[1]; 46 | } 47 | }; 48 | 49 | void webMain() 50 | { 51 | //Test JS-layout struct 52 | __asm__("var a=new JsStruct(3.0,42); a.test()"); 53 | assertEqual(testSuccessful, true, "JS interoperability using [[cheerp::jsexport]]/__asm__ 1/3"); 54 | __asm__("var a=new JsStruct2(); a.set_b(43); a.test()"); 55 | assertEqual(testSuccessful2, true, "JS interoperability using [[cheerp::jsexport]]/__asm__ 2/3"); 56 | client::Object* tmp; 57 | __asm__("new JsStruct2()" : "=r"(tmp)); 58 | float ret; 59 | __asm__("%1.testptr(new Float32Array([0,0,42.5]), 1)" : "=r"(ret) : "r"(tmp)); 60 | assertEqual(ret, 42.5f, "JS interoperability using [[cheerp::jsexport]]/__asm__ 3/3"); 61 | } 62 | -------------------------------------------------------------------------------- /tests/unit/types/test8.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | int a; 11 | A():a(42) 12 | { 13 | } 14 | }; 15 | 16 | class B 17 | { 18 | public: 19 | A a[2]; 20 | }; 21 | 22 | void webMain() 23 | { 24 | B b; 25 | assertEqual(b.a[1].a, 42, "Initialization of arrays in classes"); 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/types/test9.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A 8 | { 9 | public: 10 | int a; 11 | }; 12 | 13 | class B: public A 14 | { 15 | public: 16 | int b; 17 | }; 18 | 19 | class C: public B 20 | { 21 | public: 22 | int c; 23 | }; 24 | 25 | void webMain() 26 | { 27 | C c; 28 | B* b = &c; 29 | A* a = &c; 30 | B* b2 = static_cast(a); 31 | assertEqual(b, b2, "Pointer equality for classes with downcast array"); 32 | } 33 | -------------------------------------------------------------------------------- /tests/unit/types/union64.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2019 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | #include 7 | 8 | union U 9 | { 10 | double d; 11 | uint64_t u64; 12 | }; 13 | 14 | void webMain() 15 | { 16 | //Test union with uint64_t 17 | U u; 18 | u.d = M_PI; 19 | assertEqual(u.u64, 4614256656552045848, "Access to union with unt64_t member 1/2"); 20 | u.d = 0.0; 21 | u.u64 = 4614256656552045848; 22 | assertEqual(u.d, M_PI, "Access to union with unt64_t member 2/2"); 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/vbases/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===---------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct X 8 | { 9 | double x; 10 | virtual ~X() 11 | { 12 | } 13 | }; 14 | 15 | struct J { 16 | int j{10}; 17 | virtual ~J() 18 | { 19 | } 20 | }; 21 | struct K { 22 | int k{20}; 23 | virtual int f() { 24 | return k; 25 | } 26 | }; 27 | struct B: public K, public J 28 | { 29 | int b; 30 | B():b(1){} 31 | virtual ~B() 32 | { 33 | } 34 | virtual int f() override 35 | { 36 | return b; 37 | } 38 | }; 39 | 40 | struct A: public X, public virtual B 41 | { 42 | int a; 43 | A():a(2){} 44 | ~A() 45 | { 46 | } 47 | int f() override 48 | { 49 | return a; 50 | } 51 | }; 52 | 53 | void webMain() 54 | { 55 | A a; 56 | A* volatile a2=&a; 57 | B* volatile b=&a; 58 | K* volatile k=&a; 59 | 60 | assertEqual(2, b->f(), "Virtual Bases This adjustment 1/3"); 61 | assertEqual(2, a2->f(), "Virtual Bases This adjustment 2/3"); 62 | assertEqual(2, k->f(), "Virtual Bases This adjustment 3/3"); 63 | } 64 | -------------------------------------------------------------------------------- /tests/unit/vbases/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===---------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct X { 8 | int x{10}; 9 | virtual int foo() { 10 | return x; 11 | }; 12 | }; 13 | struct Y { 14 | int y{20}; 15 | virtual int bar() { 16 | return y; 17 | }; 18 | }; 19 | struct A: public Y, public X { 20 | int a{1}; 21 | virtual int foo() { 22 | return a; 23 | } 24 | }; 25 | struct B: virtual A { 26 | int b{2}; 27 | virtual int foo() { 28 | return b; 29 | } 30 | }; 31 | struct C: virtual B { 32 | int c{3}; 33 | virtual int foo() { 34 | return c; 35 | } 36 | }; 37 | struct D: virtual C { 38 | int d{4}; 39 | }; 40 | 41 | 42 | int foo(X* x) { 43 | return x->foo(); 44 | } 45 | void webMain() 46 | { 47 | D d; 48 | X* x = &d; 49 | int ret = foo(x); 50 | assertEqual(3, ret, "Virtual This adjustment diamond hierarchy 1/1"); 51 | } 52 | -------------------------------------------------------------------------------- /tests/unit/vbases/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===---------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct J { 8 | int j{100}; 9 | virtual ~J(){} 10 | }; 11 | struct K { 12 | int k{200}; 13 | virtual int bar() { 14 | return k; 15 | } 16 | }; 17 | 18 | struct X: public J, public virtual K { 19 | int x{10}; 20 | virtual int bar() { 21 | return x; 22 | } 23 | }; 24 | 25 | struct Y: public X { 26 | int y{20}; 27 | virtual int bar() { 28 | return y; 29 | } 30 | }; 31 | 32 | 33 | struct A { 34 | int a{1}; 35 | virtual K* foo() { 36 | return new X(); 37 | } 38 | }; 39 | 40 | struct B: public virtual A { 41 | int b{2}; 42 | virtual Y* foo() override { 43 | return new Y(); 44 | } 45 | }; 46 | 47 | int foo(A* a) { 48 | K* k = a->foo(); 49 | return k->bar(); 50 | } 51 | 52 | void webMain() 53 | { 54 | B b; 55 | int ret = foo(&b); 56 | assertEqual(20, ret, "Virtual Bases Return adjustment 1/1"); 57 | } 58 | -------------------------------------------------------------------------------- /tests/unit/vbases/test4.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===---------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct X 8 | { 9 | double x; 10 | virtual ~X() 11 | { 12 | } 13 | }; 14 | 15 | struct J { 16 | int j{10}; 17 | virtual int aaaaa() { 18 | return j; 19 | } 20 | }; 21 | struct K { 22 | int k{20}; 23 | virtual int f() { 24 | return k; 25 | } 26 | }; 27 | struct B: public virtual K, public J 28 | { 29 | int b; 30 | B():b(1){} 31 | virtual ~B() 32 | { 33 | } 34 | virtual int f() override 35 | { 36 | return b; 37 | } 38 | }; 39 | 40 | struct A: public X, public virtual B 41 | { 42 | int a; 43 | A():a(2){} 44 | ~A() 45 | { 46 | } 47 | int f() override 48 | { 49 | return a; 50 | } 51 | }; 52 | 53 | void webMain() 54 | { 55 | A a; 56 | A* volatile a2=&a; 57 | B* volatile b=&a; 58 | K* volatile k=&a; 59 | J* volatile j=&a; 60 | A* volatile a3=dynamic_cast(k); 61 | B* volatile b2=dynamic_cast(k); 62 | K* volatile k2=dynamic_cast(j); 63 | assertEqual(2, a3->f(), "dynamic_cast with virtual bases 1/3"); 64 | assertEqual(2, b2->f(), "dynamic_cast with virtual bases 2/3"); 65 | assertEqual(2, k2->f(), "dynamic_cast with virtual bases 3/3"); 66 | } 67 | -------------------------------------------------------------------------------- /tests/unit/vbases/test5.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===---------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | class A { 8 | public: 9 | virtual ~A() { } 10 | }; 11 | 12 | class B : virtual public A { 13 | }; 14 | 15 | class C : public B, virtual public A { 16 | public: 17 | virtual int foo(); 18 | }; 19 | 20 | int C::foo() 21 | { 22 | return 1; 23 | } 24 | void webMain() 25 | { 26 | C c; 27 | int ret = c.foo(); 28 | assertEqual(1, ret, "Nearly empty virtual bases 1/1"); 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/virtual/constructor.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | double x; 10 | A():x(f()) 11 | { 12 | assertEqual(x, 42.0, "Virtual calls in constructor 1/3"); 13 | } 14 | virtual int f() 15 | { 16 | return 42; 17 | } 18 | }; 19 | 20 | struct B: public A 21 | { 22 | int b; 23 | B():b(f()) 24 | { 25 | assertEqual(b, 43, "Virtual calls in constructor 2/3"); 26 | } 27 | virtual int f() 28 | { 29 | return 43; 30 | } 31 | }; 32 | 33 | void webMain() 34 | { 35 | B* b = new B(); 36 | assertEqual(b->b, 43, "Virtual calls in constructor 3/3"); 37 | } 38 | -------------------------------------------------------------------------------- /tests/unit/virtual/interop.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2018 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct [[cheerp::genericjs]] A 8 | { 9 | virtual int f() 10 | { 11 | return 42; 12 | } 13 | virtual ~A() 14 | { 15 | } 16 | }; 17 | 18 | struct [[cheerp::genericjs]] B: public A 19 | { 20 | virtual int f() 21 | { 22 | return 43; 23 | } 24 | }; 25 | 26 | struct [[cheerp::wasm]] C 27 | { 28 | virtual int f() 29 | { 30 | return 44; 31 | } 32 | virtual ~C() 33 | { 34 | } 35 | }; 36 | 37 | struct [[cheerp::wasm]] D: public C 38 | { 39 | virtual int f() 40 | { 41 | return 45; 42 | } 43 | }; 44 | 45 | [[cheerp::genericjs]] int runGeneric(A* a) 46 | { 47 | return a->f(); 48 | } 49 | 50 | [[cheerp::wasm]] int runWasm(C* c) 51 | { 52 | return c->f(); 53 | } 54 | 55 | void webMain() 56 | { 57 | B b; 58 | D d; 59 | A* volatile a = &b; 60 | C* volatile c = &d; 61 | assertEqual(runGeneric(a), 43, "Virtual calls in both modes 1/2"); 62 | assertEqual(runWasm(c), 45, "Virtual calls in both modes 2/2"); 63 | } 64 | -------------------------------------------------------------------------------- /tests/unit/virtual/test1.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct X 8 | { 9 | double x; 10 | virtual ~X() 11 | { 12 | } 13 | }; 14 | 15 | struct B 16 | { 17 | int b; 18 | B():b(1){} 19 | virtual ~B() 20 | { 21 | } 22 | virtual int f() 23 | { 24 | return b; 25 | } 26 | }; 27 | 28 | struct A: public X, public B 29 | { 30 | int a; 31 | A():a(2){} 32 | ~A() 33 | { 34 | } 35 | int f() 36 | { 37 | return a; 38 | } 39 | }; 40 | 41 | void webMain() 42 | { 43 | A a; 44 | A* volatile a2=&a; 45 | B* volatile b=&a; 46 | 47 | assertEqual(b->f(), 2, "Simple virtual call 1/2"); 48 | assertEqual(a2->f(),2, "Simple virtual call 2/2"); 49 | } 50 | -------------------------------------------------------------------------------- /tests/unit/virtual/test2.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2013 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int a; 10 | virtual int f() 11 | { 12 | return 1; 13 | } 14 | virtual ~A() 15 | { 16 | } 17 | }; 18 | 19 | struct B: public A 20 | { 21 | virtual int f() 22 | { 23 | return 2; 24 | } 25 | virtual ~B() 26 | { 27 | } 28 | }; 29 | 30 | struct C: public B 31 | { 32 | virtual int f() 33 | { 34 | return 3; 35 | } 36 | virtual ~C() 37 | { 38 | } 39 | }; 40 | 41 | void webMain() 42 | { 43 | C c; 44 | C* volatile c2=&c; 45 | B* volatile b=c2; 46 | A* volatile a=c2; 47 | C* volatile c3=static_cast(a); 48 | 49 | assertEqual(a->f(), 3, "Complex virtual call 1/5"); 50 | assertEqual(b->f(), 3, "Complex virtual call 2/5"); 51 | assertEqual(c.f(), 3, "Complex virtual call 3/5"); 52 | 53 | B b2; 54 | A* volatile a2=&b2; 55 | assertEqual(a2->f(), 2, "Complex virtual call 4/5"); 56 | assertEqual(b2.f(), 2, "Complex virtual call 5/5"); 57 | } 58 | -------------------------------------------------------------------------------- /tests/unit/virtual/test3.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------------------------------------------------===// 2 | // Copyright 2015 Leaning Technlogies 3 | //===----------------------------------------------------------------------===// 4 | 5 | #include 6 | 7 | struct A 8 | { 9 | int a; 10 | A():a(1) 11 | { 12 | } 13 | virtual A* clone() 14 | { 15 | return new A(*this); 16 | } 17 | virtual ~A() 18 | { 19 | } 20 | }; 21 | 22 | struct B: public A 23 | { 24 | B() 25 | { 26 | a=2; 27 | } 28 | virtual ~B() 29 | { 30 | } 31 | virtual B* clone() 32 | { 33 | return new B(*this); 34 | } 35 | }; 36 | 37 | struct C 38 | { 39 | virtual ~C() 40 | { 41 | } 42 | int c; 43 | }; 44 | 45 | struct D: public C, public A 46 | { 47 | D() 48 | { 49 | a=3; 50 | } 51 | virtual ~D() 52 | { 53 | } 54 | virtual D* clone() 55 | { 56 | return new D(*this); 57 | } 58 | }; 59 | 60 | void webMain() 61 | { 62 | B b; 63 | A* volatile a=&b; 64 | A* a2=a->clone(); 65 | B* b2=b.clone(); 66 | 67 | assertEqual(a2->a, 2, "Covariant return types 1/4"); 68 | assertEqual(b2->a, 2, "Covariant return types 2/4"); 69 | 70 | D d; 71 | A* volatile a3=&d; 72 | A* a4=a3->clone(); 73 | D* d2=d.clone(); 74 | 75 | assertEqual(a4->a, 3, "Covariant return types 3/4"); 76 | assertEqual(d2->a, 3, "Covariant return types 4/4"); 77 | } 78 | -------------------------------------------------------------------------------- /tests/webgl/Makefile: -------------------------------------------------------------------------------- 1 | include ../tests.make 2 | 3 | all: webgl.js 4 | -------------------------------------------------------------------------------- /tests/webgl/webgl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tools/CheerpCommon.cmake.in: -------------------------------------------------------------------------------- 1 | list(APPEND CMAKE_MODULE_PATH "@CHEERP_PREFIX@/share/cmake/Modules") 2 | # specify the cross compiler 3 | SET(CMAKE_C_COMPILER @CHEERP_PREFIX@/bin/clang CACHE FILEPATH "C Compiler") 4 | SET(CMAKE_CXX_COMPILER @CHEERP_PREFIX@/bin/clang++ CACHE FILEPATH "C++ Compiler") 5 | SET(CMAKE_LINKER @CHEERP_PREFIX@/bin/llvm-link CACHE FILEPATH "Linker") 6 | 7 | # CMake compiler autodetection does not work with .bc, .wasm or .js files, 8 | # so we ask him to trust us that the compiler works and it is Clang 9 | foreach(LANG in LISTS C CXX) 10 | set(CMAKE_${LANG}_COMPILER_FRONTEND_VARIANT GNU) 11 | set(CMAKE_${LANG}_STANDARD_COMPUTED_DEFAULT 11) 12 | set(CMAKE_${LANG}_COMPILER_ID_RUN TRUE) 13 | set(CMAKE_${LANG}_COMPILER_ID Clang) 14 | set(CMAKE_${LANG}_COMPILER_VERSION @CHEERP_VERSION@) 15 | set(CMAKE_${LANG}_COMPILER_FORCED FALSE) 16 | endforeach() 17 | 18 | # where is the target environment 19 | SET(CMAKE_FIND_ROOT_PATH @CHEERP_PREFIX@) 20 | 21 | # search for programs in the build host directories 22 | SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 23 | # for libraries and headers in the target directories 24 | SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 25 | SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 26 | 27 | SET(CMAKE_SYSTEM_INCLUDE_PATH "/include") 28 | 29 | # this one is important 30 | SET(CMAKE_SYSTEM_NAME Cheerp) 31 | #this one not so much 32 | SET(CMAKE_SYSTEM_VERSION 1) 33 | -------------------------------------------------------------------------------- /tools/CheerpToolchain.cmake: -------------------------------------------------------------------------------- 1 | SET(CMAKE_CXX_COMPILER_TARGET cheerp) 2 | SET(CMAKE_C_COMPILER_TARGET cheerp) 3 | 4 | include("${CMAKE_CURRENT_LIST_DIR}/CheerpCommon.cmake") 5 | -------------------------------------------------------------------------------- /tools/CheerpWasiToolchain.cmake: -------------------------------------------------------------------------------- 1 | SET(CMAKE_CXX_COMPILER_TARGET cheerp-wasm-wasi) 2 | SET(CMAKE_C_COMPILER_TARGET cheerp-wasm-wasi) 3 | 4 | include("${CMAKE_CURRENT_LIST_DIR}/CheerpCommon.cmake") 5 | -------------------------------------------------------------------------------- /tools/CheerpWasmToolchain.cmake: -------------------------------------------------------------------------------- 1 | SET(CMAKE_CXX_COMPILER_TARGET cheerp-wasm) 2 | SET(CMAKE_C_COMPILER_TARGET cheerp-wasm) 3 | 4 | include("${CMAKE_CURRENT_LIST_DIR}/CheerpCommon.cmake") 5 | --------------------------------------------------------------------------------