Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/generators/genlua.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2215,7 +2215,7 @@ let generate com =
List.iter (generate_type_forward ctx) com.types; newline ctx;

(* Generate some dummy placeholders for utility libs that may be required*)
println ctx "local _hx_bind, _hx_bit, _hx_staticToInstance, _hx_funcToField, _hx_anonToField, _hx_maxn, _hx_print, _hx_apply_self, _hx_box_mr, _hx_bit_clamp, _hx_table, _hx_bit_raw";
println ctx "local _hx_bind, _hx_bit, _hx_staticToInstance, _hx_funcToField, _hx_anonToField, _hx_maxn, _hx_print, _hx_apply_self, _hx_box_mr, _hx_table, _hx_bit_raw";
println ctx "local _hx_pcall_default = {};";
println ctx "local _hx_pcall_break = {};";

Expand All @@ -2227,9 +2227,6 @@ let generate com =
print_file (find_file "lua/_lua/_hx_bit.lua");
end;

(* integer clamping is always required, and will use bit ops if available *)
print_file (find_file "lua/_lua/_hx_bit_clamp.lua");

(* Array is required, always patch it *)
println ctx "_hx_array_mt.__index = Array.prototype";
newline ctx;
Expand Down
87 changes: 83 additions & 4 deletions std/lua/Boot.hx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class Boot {
static var _:Dynamic;
static var _fid = 0;

static var Max_Int32 = 2147483647;
static var Min_Int32 = -2147483648;
static inline var Max_Int32 = 2147483647;
static inline var Min_Int32 = -2147483648;


// A max stack size to respect for unpack operations
Expand Down Expand Up @@ -194,11 +194,90 @@ class Boot {
+ (if (h < 10) "0" + h else "" + h) + ":" + (if (mi < 10) "0" + mi else "" + mi) + ":" + (if (s < 10) "0" + s else "" + s);
}

// wrap with common functionality for all implementations
extern inline static function clampWrapper(inner:Float->Null<Int>):Float->Null<Int> {
return function (v:Float) {
if (v <= Max_Int32 && v >= Min_Int32)
return v > 0 ? Math.floor(v) : Math.ceil(v);

if (inline std.Math.isNaN(v) || !inline std.Math.isFinite(v))
return null;

return inner(v);
};
}

extern inline static function prepareForBitwise(v:Float) {
if (v > 2251798999999999) {
return v * 2;
}
return v;
}

// Ideally, these should be extern inline because they should only be used
// via inlining (we also don't want clampNativeOperator outside testFunctionSupport)
// however, extern inline prevents closures, even if they are immediately inlined
Comment thread
tobil4sk marked this conversation as resolved.
Outdated
inline static function clampNativeOperator(v:Float) {
v = prepareForBitwise(v);
return lua.Syntax.code("({0} & 0x7FFFFFFF) - ({0} & 0x80000000)", v);
}

inline static function clampHxBit(v:Float):Int {
v = prepareForBitwise(v);
final band:(Float, Float) -> Int = untyped _hx_bit_raw.band;
return band(v, Max_Int32) - cast Math.abs(band(v, -Min_Int32));
}

inline static function clampModulo(v:Float):Int {
v %= 4294967296;
Comment thread
tobil4sk marked this conversation as resolved.
Outdated
if (v >= 2147483648) {
v -= 4294967296;
}
return cast v;
}

/**
Test whether the syntax used in function `f` is supported on the current lua version.

If it is, return it, otherwise return null.
**/
extern inline static function testFunctionSupport<T, S>(f:T->S):Null<T->S> {
final result = Lua.pcall(Lua.load, lua.Syntax.code("[[return {0}]]", f));
if (result.status && result.value != null) {
final fn:() -> (T->S) = result.value;
return fn();
}
return null;
}

/**
A 32 bit clamp function for numbers
**/
public inline static function clampInt32(x:Float) {
return untyped _hx_bit_clamp(x);
@:ifFeature("use._bitop")
public static function clampInt32(v:Float) {
#if (lua_ver >= 5.3)
return clampWrapper(clampNativeOperator);
#else
final clampImpl = {
// Try native Lua 5.3+ bit operators first (preferred over bit32/bit library)
final nativeOperators = testFunctionSupport(clampWrapper(clampNativeOperator));
if (nativeOperators != null) {
nativeOperators;
#if !(lua_ver >= 5.2) // lua 5.2 definitely has bit32
} else if (untyped _hx_bit_raw == null) {
// Fallback for Lua without bit, bit32, or native bit ops: wrap using modulo
clampWrapper(clampModulo);
#end
} else {
clampWrapper(clampHxBit);
}
};

// set implementation so that future calls don't have to perform detection
untyped lua.Boot.clampInt32 = clampImpl;

return clampImpl(v);
#end
}

/**
Expand Down
12 changes: 6 additions & 6 deletions std/lua/_lua/_hx_bit.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ if _G.bit32 or pcall(require, 'bit32') then
_hx_bit_raw = _G.bit32 or require('bit32')
_hx_bit = setmetatable({}, { __index = _hx_bit_raw })
-- bit32 operations require manual clamping
_hx_bit.bnot = function(...) return _hx_bit_clamp(_hx_bit_raw.bnot(...)) end
_hx_bit.bxor = function(...) return _hx_bit_clamp(_hx_bit_raw.bxor(...)) end
_hx_bit.bnot = function(...) return __lua_Boot.clampInt32(_hx_bit_raw.bnot(...)) end
_hx_bit.bxor = function(...) return __lua_Boot.clampInt32(_hx_bit_raw.bxor(...)) end
-- see https://github.com/HaxeFoundation/haxe/issues/8849
_hx_bit.bor = function(...) return _hx_bit_clamp(_hx_bit_raw.bor(...)) end
_hx_bit.band = function(...) return _hx_bit_clamp(_hx_bit_raw.band(...)) end
_hx_bit.arshift = function(...) return _hx_bit_clamp(_hx_bit_raw.arshift(...)) end
_hx_bit.lshift = function(...) return _hx_bit_clamp(_hx_bit_raw.lshift(...)) end
_hx_bit.bor = function(...) return __lua_Boot.clampInt32(_hx_bit_raw.bor(...)) end
_hx_bit.band = function(...) return __lua_Boot.clampInt32(_hx_bit_raw.band(...)) end
_hx_bit.arshift = function(...) return __lua_Boot.clampInt32(_hx_bit_raw.arshift(...)) end
_hx_bit.lshift = function(...) return __lua_Boot.clampInt32(_hx_bit_raw.lshift(...)) end
elseif _G.bit or pcall(require, 'bit') then
-- if we do not have bit32, fallback to bit, default on luajit
_hx_bit_raw = _G.bit or require('bit')
Expand Down
49 changes: 0 additions & 49 deletions std/lua/_lua/_hx_bit_clamp.lua

This file was deleted.

2 changes: 1 addition & 1 deletion std/lua/_std/Array.hx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Array<T> {
public function reverse():Void {
var tmp:T;
var i = 0;
while (i < Std.int(this.length / 2)) {
while (i < Math.floor(this.length / 2)) {
tmp = this[i];
this[i] = this[this.length - i - 1];
this[this.length - i - 1] = tmp;
Expand Down
Loading