summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicolas Noble <pixel@nobis-crew.org>2013-08-12 13:25:22 -0700
committerNicolas Noble <pixel@nobis-crew.org>2013-08-12 13:25:22 -0700
commitf5e970f17e9bb3fc30cda214cf8522e4216de30f (patch)
tree6286fea5e5fd968114c6fae3c3f51ec983af21dd /src
parenta91c3d3a6cb5e71c6376b1efe7d037f02b36f035 (diff)
Fixing a few more things, added BigInt to ints conversions, and added the 64 bits read / write versions for LuaHandle.
Diffstat (limited to 'src')
-rw-r--r--src/BigInt.cc49
-rw-r--r--src/LuaHandle.cc67
-rw-r--r--src/Main.cc7
3 files changed, 117 insertions, 6 deletions
diff --git a/src/BigInt.cc b/src/BigInt.cc
index 3735ad7..7ff1422 100644
--- a/src/BigInt.cc
+++ b/src/BigInt.cc
@@ -8,12 +8,15 @@ namespace {
class InitMP : public Balau::AtStart {
public:
- InitMP() : AtStart(0) { }
+ InitMP() : AtStart(20) { }
void doStart() {
ltc_mp = ltm_desc;
+ IAssert(MP_DIGIT_BIT >= 32, "The code needs at least 32 bits digits.");
+ IAssert(MP_DIGIT_BIT <= 64, "The code needs at most 64 bits digits.");
+ IAssert(!m_initialized, "doStart should only be called once.");
m_initialized = true;
+
static Balau::BigInt s2p32;
- IAssert(!m_2p32, "doStart should only be called once.");
s2p32.set2expt(32);
m_2p32 = &s2p32;
}
@@ -132,6 +135,48 @@ void Balau::BigInt::set2expt(int i) throw (GeneralException) {
throw GeneralException("Error while calling mp_2expt");
}
+uint64_t Balau::BigInt::to_uint64() const throw (GeneralException) {
+ if (mp_get_digit_count(m_bi) > 2)
+ throw GeneralException("BigInt too big to fit in a uint64");
+ if (MP_DIGIT_BIT == 64)
+ return mp_get_digit(m_bi, 0);
+ uint64_t low = mp_get_digit(m_bi, 0);
+ uint64_t high = mp_get_digit(m_bi, 1);
+ uint64_t highest = 1 << (64 - MP_DIGIT_BIT);
+ if (high >= highest)
+ throw GeneralException("BigInt too big to fit in a uint64");
+ return low | (high << MP_DIGIT_BIT);
+}
+
+int64_t Balau::BigInt::to_int64() const throw (GeneralException) {
+ uint64_t v = to_uint64();
+ if (v & 0x8000000000000000ULL)
+ throw GeneralException("BigInt too big to fit in a int64");
+ if (comp(0) == LT)
+ return -v;
+ else
+ return v;
+}
+
+uint32_t Balau::BigInt::to_uint32() const throw (GeneralException) {
+ if (mp_get_digit_count(m_bi) > 1)
+ throw GeneralException("BigInt too big to fit in a uint32");
+ uint64_t v = mp_get_digit(m_bi, 0);
+ if (v >= 0x100000000ULL)
+ throw GeneralException("BigInt too big to fit in a uint32");
+ return v;
+}
+
+int32_t Balau::BigInt::to_int32() const throw (GeneralException) {
+ uint32_t v = to_uint32();
+ if (v & 0x80000000)
+ throw GeneralException("BigInt too big to fit in a int32");
+ if (comp(0) == LT)
+ return -v;
+ else
+ return v;
+}
+
Balau::BigInt Balau::BigInt::operator+(unsigned int i) const throw (GeneralException) {
BigInt r;
if (mp_add_d(m_bi, i, r.m_bi) != CRYPT_OK)
diff --git a/src/LuaHandle.cc b/src/LuaHandle.cc
index c7ff88a..de9e7e2 100644
--- a/src/LuaHandle.cc
+++ b/src/LuaHandle.cc
@@ -1,4 +1,5 @@
#include "LuaHandle.h"
+#include "LuaBigInt.h"
#include "Handle.h"
typedef Balau::IO<Balau::Handle> IOHandle;
@@ -11,15 +12,19 @@ enum IOHandle_methods_t {
IOHANDLE_READU8,
IOHANDLE_READU16,
IOHANDLE_READU32,
+ IOHANDLE_READU64,
IOHANDLE_READI8,
IOHANDLE_READI16,
IOHANDLE_READI32,
+ IOHANDLE_READI64,
IOHANDLE_WRITEU8,
IOHANDLE_WRITEU16,
IOHANDLE_WRITEU32,
+ IOHANDLE_WRITEU64,
IOHANDLE_WRITEI8,
IOHANDLE_WRITEI16,
IOHANDLE_WRITEI32,
+ IOHANDLE_WRITEI64,
};
struct Balau::lua_functypes_t IOHandle_methods[] = {
@@ -27,15 +32,19 @@ struct Balau::lua_functypes_t IOHandle_methods[] = {
{ IOHANDLE_READU8, "readU8", 0, 0, { } },
{ IOHANDLE_READU16, "readU16", 0, 0, { } },
{ IOHANDLE_READU32, "readU32", 0, 0, { } },
+ { IOHANDLE_READU64, "readU64", 0, 0, { } },
{ IOHANDLE_READI8, "readI8", 0, 0, { } },
{ IOHANDLE_READI16, "readI16", 0, 0, { } },
{ IOHANDLE_READI32, "readI32", 0, 0, { } },
+ { IOHANDLE_READI64, "readI64", 0, 0, { } },
{ IOHANDLE_WRITEU8, "writeU8", 1, 1, { Balau::BLUA_NUMBER } },
{ IOHANDLE_WRITEU16, "writeU16", 1, 1, { Balau::BLUA_NUMBER } },
{ IOHANDLE_WRITEU32, "writeU32", 1, 1, { Balau::BLUA_NUMBER } },
+ { IOHANDLE_WRITEU64, "writeU64", 1, 1, { Balau::BLUA_NUMBER | Balau::BLUA_OBJECT | Balau::BLUA_STRING } },
{ IOHANDLE_WRITEI8, "writeI8", 1, 1, { Balau::BLUA_NUMBER } },
{ IOHANDLE_WRITEI16, "writeI16", 1, 1, { Balau::BLUA_NUMBER } },
{ IOHANDLE_WRITEI32, "writeI32", 1, 1, { Balau::BLUA_NUMBER } },
+ { IOHANDLE_WRITEI64, "writeI64", 1, 1, { Balau::BLUA_NUMBER | Balau::BLUA_OBJECT | Balau::BLUA_STRING } },
{ -1, 0, 0, 0, 0 },
};
@@ -69,6 +78,17 @@ int sLua_IOHandle::IOHandle_proceed(Balau::Lua & L, int n, IOHandle * obj, int c
return L.yield(Balau::Future<int>([L, c]() mutable { L.push((lua_Number) c.get()); return 1; }));
}
break;
+ case IOHANDLE_READU64:
+ {
+ Balau::Future<uint64_t> c = h->readU64();
+ return L.yield(Balau::Future<int>([L, c]() mutable {
+ uint64_t v = c.get();
+ Balau::LuaBigIntFactory f(new Balau::BigInt(v));
+ f.pushDestruct(L);
+ return 1;
+ }));
+ }
+ break;
case IOHANDLE_READI8:
{
Balau::Future<int8_t> c = h->readI8();
@@ -87,6 +107,17 @@ int sLua_IOHandle::IOHandle_proceed(Balau::Lua & L, int n, IOHandle * obj, int c
return L.yield(Balau::Future<int>([L, c]() mutable { L.push((lua_Number) c.get()); return 1; }));
}
break;
+ case IOHANDLE_READI64:
+ {
+ Balau::Future<int64_t> c = h->readI64();
+ return L.yield(Balau::Future<int>([L, c]() mutable {
+ int64_t v = c.get();
+ Balau::LuaBigIntFactory f(new Balau::BigInt(v));
+ f.pushDestruct(L);
+ return 1;
+ }));
+ }
+ break;
case IOHANDLE_WRITEU8:
{
Balau::Future<void> c = h->writeU8(L.tonumber());
@@ -105,6 +136,22 @@ int sLua_IOHandle::IOHandle_proceed(Balau::Lua & L, int n, IOHandle * obj, int c
return L.yield(Balau::Future<int>([L, c]() mutable { c.run(); return 0; }));
}
break;
+ case IOHANDLE_WRITEU64:
+ {
+ uint64_t v;
+ if (L.istable()) {
+ Balau::BigInt * b = L.recast<Balau::BigInt>();
+ v = b->to_uint64();
+ } else if (L.type() == LUA_TSTRING) {
+ Balau::BigInt b(L.tostring());
+ v = b.to_uint64();
+ } else {
+ v = L.tonumber();
+ }
+ Balau::Future<void> c = h->writeU64(v);
+ return L.yield(Balau::Future<int>([L, c]() mutable { c.run(); return 0; }));
+ }
+ break;
case IOHANDLE_WRITEI8:
{
Balau::Future<void> c = h->writeI8(L.tonumber());
@@ -123,6 +170,22 @@ int sLua_IOHandle::IOHandle_proceed(Balau::Lua & L, int n, IOHandle * obj, int c
return L.yield(Balau::Future<int>([L, c]() mutable { c.run(); return 0; }));
}
break;
+ case IOHANDLE_WRITEI64:
+ {
+ int64_t v;
+ if (L.istable()) {
+ Balau::BigInt * b = L.recast<Balau::BigInt>();
+ v = b->to_int64();
+ } else if (L.type() == LUA_TSTRING) {
+ Balau::BigInt b(L.tostring());
+ v = b.to_int64();
+ } else {
+ v = L.tonumber();
+ }
+ Balau::Future<void> c = h->writeI64(v);
+ return L.yield(Balau::Future<int>([L, c]() mutable { c.run(); return 0; }));
+ }
+ break;
}
return r;
@@ -141,15 +204,19 @@ void Balau::LuaHandleFactory::pushObjectAndMembers(Lua & L) {
PUSH_METHOD(IOHandle, IOHANDLE_READU8);
PUSH_METHOD(IOHandle, IOHANDLE_READU16);
PUSH_METHOD(IOHandle, IOHANDLE_READU32);
+ PUSH_METHOD(IOHandle, IOHANDLE_READU64);
PUSH_METHOD(IOHandle, IOHANDLE_READI8);
PUSH_METHOD(IOHandle, IOHANDLE_READI16);
PUSH_METHOD(IOHandle, IOHANDLE_READI32);
+ PUSH_METHOD(IOHandle, IOHANDLE_READI64);
PUSH_METHOD(IOHandle, IOHANDLE_WRITEU8);
PUSH_METHOD(IOHandle, IOHANDLE_WRITEU16);
PUSH_METHOD(IOHandle, IOHANDLE_WRITEU32);
+ PUSH_METHOD(IOHandle, IOHANDLE_WRITEU64);
PUSH_METHOD(IOHandle, IOHANDLE_WRITEI8);
PUSH_METHOD(IOHandle, IOHANDLE_WRITEI16);
PUSH_METHOD(IOHandle, IOHANDLE_WRITEI32);
+ PUSH_METHOD(IOHandle, IOHANDLE_WRITEI64);
}
diff --git a/src/Main.cc b/src/Main.cc
index e872411..a01ad24 100644
--- a/src/Main.cc
+++ b/src/Main.cc
@@ -146,14 +146,13 @@ int Balau::Main::bootstrap(int argc, char ** argv) {
int r = 0;
m_status = STARTING;
- for (AtStart * ptr = AtStart::s_head; ptr; ptr = ptr->m_next)
- ptr->doStart();
-
try {
+ for (AtStart * ptr = AtStart::s_head; ptr; ptr = ptr->m_next)
+ ptr->doStart();
+
m_status = RUNNING;
TaskMan::registerTask(new BootstrapTask(argc, argv, NULL));
r = TaskMan::getDefaultTaskMan()->mainLoop();
- m_status = STOPPING;
}
catch (Exit & e) {
m_status = STOPPING;