Closed ghost closed 5 years ago
I see you are using Cheerp 2.0 RC1. Support for clobbering is only available in nightly builds.
Edit: Fixed for previous reference to RC2. In reality only nightly builds supports this feature.
After building cheerp from source, as detailed here, clang kept crashing every time a compilation was attempted.
I am currently rebuilding cheerp and will post logs in case I am able to replicate.
You can find ready made nightly Linux packages here: https://launchpad.net/~leaningtech-dev/+archive/ubuntu/cheerp-nightly-ppa
Same clobber list related error with nightly build.
/opt/cheerp/bin/clang++ --version
Cheerp 1516806243-1~xenial clang version 3.7.0 (based on LLVM 3.7.0svn)
Target: x86_64-pc-linux-gnu
Thread model: posix
Transpiling to JavaScript...
mylib.cpp:68:121: error: unknown register name 'jsTemp1' in asm
__asm__("var jsTemp1=%0; var jsTemp2=jsTemp1+1; console.log(jsTemp2);" : /*No output*/ : "r"(42) : /*Clobber list*/ "jsTemp1","jsTemp2"); // This will print out "43"
Since you are using xenial you are getting an older version. You can force Ubuntu to use the newer repo by replacing xenial
with bionic
in /etc/apt/sources.list.d/leaningtech-dev*.list
Alright, with
/opt/cheerp/bin/clang++ --version
Cheerp 1545237965-1~bionic clang version 3.7.0 (based on LLVM 3.7.0svn)
Target: x86_64-pc-linux-gnu
Thread model: posix
... there is no more complaining about unknown register names, however things that used to work before aren't working anymore. Is this nightly build including breaking changes?
From example, the following code (copy paste from here):
void webMain() {
__asm__("console.log('Inline JS example')");
}
Error:
Transpiling to JavaScript...
internal.cpp:59:5: error: Cheerp: Cannot use inline asm in a 'asmjs' function
__asm__("console.log('Inline JS example')");
^
That's funny, because I am transpiling with-cheerp-mode=wasm
.
Decorating webMain with [[cheerp::wasm]]
merely changes the error message to error: Cheerp: Cannot use inline asm in a 'wasm' function
Then I have a class with no cheerp::genericjs attribute, which should be compiled to WebAssembly:
class Container {
public:
Container() = default;
~Container() = default;
std::string fn001();
private:
std::vector<wchar_t> data;
std::vector<std::function<client::String(unsigned int)>> functors;
int (*non_member_func_array[4]) (int x, int y);
int (Container::*member_func_array[]) (int x, int y);
};
If I dump asm in fn001's implementation:
std::string Container::fn001() {
__asm__("console.log('Inline JS example')");
return std::string();
}
error: Cheerp: Cannot use inline asm in a 'asmjs' function
__asm__("console.log('Inline JS example')");
^
It appears that _asm_
only works within member functions of classes decorated with [[cheerp::genericjs]]
attribute and cannot be made use of elsewhere. Can you confirm this?
I'm beginning to wonder if it weren't simpler to revert back to RC1, renounce clobber lists, transpile with -pretty-code
and then run the output through closure compiler for minification. Would that be a thing?
As the error message says, you cannot use __asm__
to put JavaScript in the middle of wasm or asmjs functions. That is by design. If you want to use inline JavaScript you need to tag a method as [[cheerp::genericjs]]
Keep in mind that [[cheerp::asmjs]]
and [[cheerp::wasm]]
have the same semantics and are interchangeable. The actual output format is decided by -cheerp-mode=
Also, to clarify, this was not supported in RC1 as well. The code would compile but be broken before, so the current version is actually more robust.
What about webMain
? _asm_
should be possible in webMain
(the docs say as much), however the following example from the docs does no transpile:
void webMain() {
__asm__("console.log('Inline JS example')");
}
Error:
Transpiling to JavaScript...
internal.cpp:59:5: error: Cheerp: Cannot use inline asm in a 'asmjs' function
__asm__("console.log('Inline JS example')");
^
I'm confused as of why this fails for webMain
. The documentation makes no reference of decorating webMain
with [[cheerp::genericjs]]
attribute. If I decorate webMain
with [[cheerp::genericjs]]
it transpiles just fine, however I'm not sure if this is the recommended approach.
webMain
is the entry point of the application, independently of the compilation mode. If you compile with -cheerp-mode=asmjs
or -cheerp-mode=wasm
all the non-tagged function will default to asmjs/wasm mode.
The documentation for __asm__
uses webMain just as an example.
Makes sense now. Thank you for the input. :)
Hello,
I thought cheerp should be able to understand that temporary variables in clobber list are not valid CPU register names. However, I am not able to transpile code decorated with non-empty clobber list
_asm_
.CMakeLists.txt
Code
Error
Cheerp info
Quite confusing... :|