Open ilevd opened 1 year ago
So, I have success and reproduce it:
Strucrute:
Main.hx
lang/
EdnReader.hx
Keyword.hx
Murmur3.hx
Symbol.hx
build.hxml
Main.hx
import lang.EdnReader;
class Main {
static public function main() {}
}
EdnReader.hx
package lang;
class EdnReader {
static final V:Keyword = Keyword.create();
}
Keyword.hx
package lang;
class Keyword {
var h:Int;
public function new(sym:Symbol) {
h = sym.hasheq() + 0x9e3779b9;
}
public static function create():Keyword {
return new Keyword(Symbol.create());
}
}
Symbol.hx
package lang;
class Symbol {
public static function create():Symbol {
return new Symbol();
}
public function new() {}
public function hasheq():Int {
return Murmur3.hash("some string");
}
}
Murmur3.hx
package lang;
final class Murmur3 {
private static final seed:Int = 0;
private static final C1:Int = 0xcc9e2d51;
private static final C2:Int = 0x1b873593;
public static function hash(input:String):Int {
// ERROR: Got:
// Static vars: ,null,null,null
// instead of values
trace("Static vars: ", seed, C1, C2);
return 0;
}
}
build.hxml
-cp src
-main Main
--each
--interp
Static initialization order is generally undefined. You can see the problem if you check the output of the JavaScript target:
lang_EdnReader.V = lang_Keyword.create();
lang_Murmur3.seed = 0;
lang_Murmur3.C1 = -862048943;
lang_Murmur3.C2 = 461845907;
Main.main();
The compiler makes some effort to find a good order, but it doesn't deeply inspect every expression because this problem is not always solvable at compile-time anyway.
We could perhaps prioritize static inits that definitely don't depend on anything else, like that Murmur3
class here. However, that won't work with your Int64
version because in that case it depends on the In64 run-time support:
lang_EdnReader.V = lang_Keyword.create();
lang_Murmur3.seed = haxe_Int64Helper.fromFloat(0);
lang_Murmur3.C1 = haxe_Int64Helper.fromFloat(-862048943);
lang_Murmur3.C2 = haxe_Int64Helper.fromFloat(461845907);
Main.main();
Hmm, maybe we could use our internal module dependency list here, and only employ the current expression exploration on cycles. I'll have to think about that!
Thank you. I handle this by making these constants inline, but later I encounter the error like in https://github.com/HaxeFoundation/haxe/issues/10562 and it seems similar, so maybe at least to do such simple static vars inline where possible to reduce the amount of such errors?
I have Murmur3 hash implementation with such in the begining:
Unfortunately, when I try to access these fields, they are null and I get an error:
I run it with
--interp
.I don't know how that can be, and that is really strange, because when I try to make simple example to reproduce the error - it works.
Maybe it happens only in my project, because there are many classes, inheritance etc or somehow related to math operations in cache algorithm, because of some mix with Int and Int64. At least Haxe doesn't provide any message when writing:
But if write:
There is: "Float should be Int".
But even if I replace Int64 with
Int
with simple values like 0 or 1, I still have such error.