Skip to content

Commit 2b06c4c

Browse files
authored
Merge pull request #1885 from nicolasnoble/bundle
Bunch of changes all around.
2 parents 28ad5de + d289b0c commit 2b06c4c

File tree

17 files changed

+363
-68
lines changed

17 files changed

+363
-68
lines changed

src/core/psxemulator.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void PCSX::Emulator::setLua() {
9090
return L.error("t_ expects a string");
9191
}
9292
auto str = L.tostring(1);
93-
L.push(g_system->getStr(djbHash::hash(str), str.c_str()));
93+
L.push(g_system->getStr(djb::hash(str), str.c_str()));
9494
return 1;
9595
});
9696
L.load("ffi = require('ffi')", "internal:setffi.lua");

src/core/system.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ bool PCSX::System::loadLocale(const std::string& name, const std::filesystem::pa
232232
if (!currentString.empty() && !fuzzy) locale[hashValue] = currentString;
233233
break;
234234
case WAITING_MSGSTRTOKEN:
235-
hashValue = djbHash::hash(currentString);
235+
hashValue = djb::hash(currentString);
236236
break;
237237
}
238238
currentString = "";

src/core/system.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ extern System *g_system;
291291

292292
// i18n macros
293293
// Normal string lookup to const char *
294-
#define _(str) PCSX::g_system->getStr(PCSX::djbHash::ctHash(str), str)
294+
#define _(str) PCSX::g_system->getStr(PCSX::djb::ctHash(str), str)
295295
// Formatting string lookup to use with fmt::format or fmt::printf
296-
#define f_(str) fmt::runtime(PCSX::g_system->getStr(PCSX::djbHash::ctHash(str), str))
296+
#define f_(str) fmt::runtime(PCSX::g_system->getStr(PCSX::djb::ctHash(str), str))
297297
// Lambda string lookup to use with static arrays of strings
298-
#define l_(str) []() { return PCSX::g_system->getStr(PCSX::djbHash::ctHash(str), str); }
298+
#define l_(str) []() { return PCSX::g_system->getStr(PCSX::djb::ctHash(str), str); }

src/lua/extra.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "lua/luawrapper.h"
2929
#include "support/file.h"
3030
#include "support/strings-helpers.h"
31+
#include "support/djbhash.h"
3132
#include "support/zip.h"
3233

3334
namespace {
@@ -81,6 +82,30 @@ PCSX::File* load(std::string_view name, std::string_view from, bool inArchives =
8182
return new PCSX::PosixFile(absolutePath);
8283
}
8384

85+
uint64_t djbHash(const char* str, size_t len) {
86+
return PCSX::djb::hash(str, len);
87+
}
88+
89+
template <typename T, size_t S>
90+
void registerSymbol(PCSX::Lua L, const char (&name)[S], const T ptr) {
91+
L.push<S>(name);
92+
L.push((void*)ptr);
93+
L.settable();
94+
}
95+
96+
#define REGISTER(L, s) registerSymbol(L, #s, s)
97+
98+
void registerAllSymbols(PCSX::Lua L) {
99+
L.getfieldtable("_CLIBS", LUA_REGISTRYINDEX);
100+
L.push("SUPPORT_EXTRA");
101+
L.newtable();
102+
103+
REGISTER(L, djbHash);
104+
105+
L.settable();
106+
L.pop();
107+
}
108+
84109
} // namespace
85110

86111
PCSX::ZipArchive& PCSX::LuaFFI::addArchive(Lua L, IO<File> file) {
@@ -138,6 +163,7 @@ void PCSX::LuaFFI::open_extra(Lua L) {
138163
static const char* extra = (
139164
#include "lua/extra.lua"
140165
);
166+
registerAllSymbols(L);
141167
L.load(pprint, "third_party:pprint.lua/pprint.lua");
142168
L.load(pprint_internals, "third_party:pprint.lua/pprint-internals.lua");
143169
L.load(reflectFFI, "third_party:ffi-reflect/reflect.lua");

src/lua/extra.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515
-- along with this program; if not, write to the
1616
-- Free Software Foundation, Inc.,
1717
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18+
19+
ffi.cdef [[
20+
uint64_t djbHash(const char* str, size_t len);
21+
]]
22+
23+
local C = ffi.load 'SUPPORT_EXTRA'
24+
1825
Support.extra = {
1926

2027
loadfile = function(name) return loadstring(Support._internal.loadfile(name), '@' .. name) end,
@@ -33,5 +40,8 @@ Support.extra = {
3340
error('FFI call failed in ' .. name .. ': ' .. ret)
3441
end,
3542

43+
djbHash = function(str)
44+
return C.djbHash(str, #str)
45+
end,
3646
}
3747
-- )EOF"

src/lua/fileffi-cdef.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,11 @@ LuaFile* dupFile(LuaFile*);
8989

9090
LuaFile* zReader(LuaFile*, int64_t size, bool raw);
9191

92+
LuaSlice* createEmptySlice();
9293
uint64_t getSliceSize(LuaSlice*);
9394
const void* getSliceData(LuaSlice*);
95+
void* getSliceMutableData(LuaSlice*);
96+
void resizeSlice(LuaSlice* slice, uint32_t size);
9497
void destroySlice(LuaSlice*);
9598

9699
LuaFile* mem4g();

src/lua/fileffimeta.lua

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,28 @@ local sliceMeta = {
2727
return buffer[index]
2828
elseif index == 'data' then
2929
return C.getSliceData(slice._wrapper)
30+
elseif index == 'mutable' then
31+
return C.getSliceMutableData(slice._wrapper)
3032
elseif index == 'size' then
3133
return tonumber(C.getSliceSize(slice._wrapper))
34+
elseif index == 'resize' then
35+
return function(slice, size)
36+
C.resizeSlice(slice._wrapper, size)
37+
end
3238
end
3339
error('Unknown index `' .. index .. '` for LuaSlice')
3440
end,
35-
__newindex = function(slice, index, value) end,
41+
__newindex = function(slice, index, value)
42+
if type(index) == 'number' and index >= 0 and index < C.getSliceSize(slice._wrapper) then
43+
local data = C.getSliceMutableData(slice._wrapper)
44+
local buffer = ffi.cast('uint8_t*', data)
45+
buffer[index] = value
46+
elseif index == 'size' then
47+
C.resizeSlice(slice._wrapper, value)
48+
else
49+
error('Unknown or immutable index `' .. index .. '` for LuaSlice')
50+
end
51+
end,
3652
}
3753

3854
local function createSliceWrapper(wrapper)
@@ -71,5 +87,6 @@ local LuaBuffer = ffi.metatype('LuaBuffer', bufferMeta)
7187

7288
Support.File._LuaBuffer = LuaBuffer
7389
Support.File._createSliceWrapper = createSliceWrapper
90+
Support.File.createEmptySlice = function() return createSliceWrapper(C.createEmptySlice()) end
7491

7592
-- )EOF"

src/lua/luafile.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,11 @@ LuaFile* zReader(LuaFile* wrapper, int64_t size, bool raw) {
167167
: new PCSX::ZReader(wrapper->file, size));
168168
}
169169

170+
PCSX::Slice* createEmptySlice() { return new PCSX::Slice(); }
170171
uint64_t getSliceSize(PCSX::Slice* slice) { return slice->size(); }
171-
172172
const void* getSliceData(PCSX::Slice* slice) { return slice->data(); }
173-
173+
void* getSliceMutableData(PCSX::Slice* slice) { return slice->mutableData(); }
174+
void resizeSlice(PCSX::Slice* slice, uint32_t size) { slice->resize(size); }
174175
void destroySlice(PCSX::Slice* slice) { delete slice; }
175176

176177
int readFileUserData(PCSX::Lua L) {
@@ -343,8 +344,11 @@ static void registerAllSymbols(PCSX::Lua L) {
343344

344345
REGISTER(L, zReader);
345346

347+
REGISTER(L, createEmptySlice);
346348
REGISTER(L, getSliceSize);
347349
REGISTER(L, getSliceData);
350+
REGISTER(L, getSliceMutableData);
351+
REGISTER(L, resizeSlice);
348352
REGISTER(L, destroySlice);
349353

350354
REGISTER(L, mem4g);

src/mips/common/util/bitfield.hh

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
3+
MIT License
4+
5+
Copyright (c) 2025 PCSX-Redux authors
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
*/
26+
27+
#include <stdint.h>
28+
29+
#include <concepts>
30+
#include <type_traits>
31+
32+
#include "util.h"
33+
34+
namespace Utilities {
35+
36+
namespace BitFieldInternal {
37+
38+
template <typename T>
39+
struct DefaultBitSize {
40+
static constexpr unsigned size = sizeof(T) * 8;
41+
};
42+
43+
template <>
44+
struct DefaultBitSize<bool> {
45+
static constexpr unsigned size = 1;
46+
};
47+
48+
template <typename... T>
49+
struct ComputeStorage {
50+
static constexpr unsigned size() { return (sizeInBits() + 7) / 8; }
51+
52+
private:
53+
static constexpr unsigned sizeInBits() { return recSize<0, T...>(); }
54+
template <unsigned index>
55+
static constexpr unsigned recSize() {
56+
return 0;
57+
}
58+
template <unsigned index, typename One, typename... Rest>
59+
static constexpr unsigned recSize() {
60+
return One::Width + recSize<index + 1, Rest...>();
61+
}
62+
};
63+
64+
template <typename Target, typename... T>
65+
struct ComputeOffset {
66+
static constexpr unsigned offset() { return recOffset<0, T...>(); }
67+
68+
private:
69+
template <unsigned index>
70+
static constexpr unsigned recOffset() {
71+
return 0;
72+
}
73+
template <unsigned index, typename One, typename... Rest>
74+
static constexpr unsigned recOffset() {
75+
if constexpr (std::is_same_v<Target, One>) {
76+
return 0;
77+
} else {
78+
return recOffset<index + 1, Rest...>() + One::Width;
79+
}
80+
}
81+
};
82+
83+
} // namespace BitFieldInternal
84+
85+
template <std::integral T, unsigned width = BitFieldInternal::DefaultBitSize<T>::size>
86+
struct BitSpan {
87+
static constexpr unsigned Width = width;
88+
using Underlying = T;
89+
};
90+
91+
template <typename... T>
92+
struct BitField {
93+
template <typename One>
94+
constexpr typename One::Underlying get() {
95+
if constexpr (std::is_signed_v<typename One::Underlying>) {
96+
return get<BitFieldInternal::ComputeOffset<One, T...>::offset(), One::Width, signed>();
97+
} else if constexpr (std::is_unsigned_v<typename One::Underlying>) {
98+
return get<BitFieldInternal::ComputeOffset<One, T...>::offset(), One::Width, unsigned>();
99+
}
100+
return 0;
101+
}
102+
template <typename One>
103+
constexpr void set(typename One::Underlying v) {
104+
if constexpr (std::is_signed_v<typename One::Underlying>) {
105+
set<BitFieldInternal::ComputeOffset<One, T...>::offset(), One::Width, signed>(v);
106+
} else if constexpr (std::is_unsigned_v<typename One::Underlying>) {
107+
set<BitFieldInternal::ComputeOffset<One, T...>::offset(), One::Width, unsigned>(v);
108+
}
109+
}
110+
111+
private:
112+
template <unsigned offset, unsigned width, std::integral U>
113+
constexpr U get() {
114+
constexpr unsigned firstByteOffset = offset / 8;
115+
constexpr unsigned lastByteOffset = (offset + width - 1) / 8;
116+
constexpr unsigned shift = offset % 8;
117+
constexpr uint32_t mask = (1 << width) - 1;
118+
if constexpr ((firstByteOffset % 4) == 0) {
119+
return reinterpret_cast<const U*>(storage)[firstByteOffset / 4] >> shift & mask;
120+
} else if constexpr ((firstByteOffset % 4) != 0) {
121+
return (loadUnaligned<U>(storage + firstByteOffset, lastByteOffset - firstByteOffset + 1) >> shift) & mask;
122+
}
123+
return 0;
124+
}
125+
template <unsigned offset, unsigned width, std::integral U>
126+
constexpr void set(U v) {
127+
constexpr unsigned firstByteOffset = offset / 8;
128+
constexpr unsigned lastByteOffset = (offset + width - 1) / 8;
129+
constexpr unsigned shift = offset % 8;
130+
constexpr uint32_t mask = (1 << width) - 1;
131+
if constexpr ((firstByteOffset % 4) == 0) {
132+
U* ptr = reinterpret_cast<U*>(storage);
133+
ptr[firstByteOffset / 4] &= ~(mask << shift);
134+
ptr[firstByteOffset / 4] |= (v & mask) << shift;
135+
} else if constexpr ((firstByteOffset % 4) != 0) {
136+
U span = loadUnaligned<U>(storage + firstByteOffset, lastByteOffset - firstByteOffset + 1);
137+
span &= ~(mask << shift);
138+
span |= (v & mask) << shift;
139+
storeUnaligned<U>(storage + firstByteOffset, span, lastByteOffset - firstByteOffset + 1);
140+
}
141+
}
142+
uint8_t storage[BitFieldInternal::ComputeStorage<T...>::size()];
143+
};
144+
145+
} // namespace Utilities

src/mips/common/util/djbhash.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,32 @@ SOFTWARE.
2828

2929
#include <stdint.h>
3030

31+
#ifdef __cplusplus
32+
#include <concepts>
33+
34+
namespace djb {
35+
36+
template <std::integral T = uint32_t>
37+
static inline constexpr T process(T hash, const char str[], unsigned n) {
38+
return n ? process(((hash << 5) + hash) ^ static_cast<uint8_t>(str[0]), str + 1, n - 1) : hash;
39+
}
40+
41+
template <std::integral T = uint32_t>
42+
static inline T constexpr hash(const char* str, unsigned n) {
43+
return process(T(5381), str, n);
44+
}
45+
46+
template <std::integral T = uint32_t, unsigned S>
47+
static inline T constexpr hash(const char (&str)[S]) {
48+
return process(T(5381), str, S - 1);
49+
}
50+
51+
} // namespace djb
52+
53+
#endif
54+
3155
static inline uint32_t djbProcess(uint32_t hash, const char str[], unsigned n) {
32-
return n ? djbProcess(((hash << 5) + hash) ^ str[0], str + 1, n - 1) : hash;
56+
return n ? djbProcess(((hash << 5) + hash) ^ ((uint8_t)str[0]), str + 1, n - 1) : hash;
3357
}
3458

3559
static inline uint32_t djbHash(const char* str, unsigned n) { return djbProcess(5381, str, n); }

0 commit comments

Comments
 (0)