Make crosslang more type safe

This commit is contained in:
2025-09-23 20:28:40 -05:00
parent c9b0578100
commit 026a9e9b49
11 changed files with 708 additions and 531 deletions

View File

@@ -1,85 +0,0 @@
#include "CrossLang.hpp"
namespace Tesses::CrossLang
{
double BitConverter::ToDoubleBits(uint64_t v)
{
return *(double*)&v;
}
uint64_t BitConverter::ToUintBits(double v)
{
return *(uint64_t*)&v;
}
double BitConverter::ToDoubleBE(uint8_t& b)
{
return ToDoubleBits(ToUint64BE(b));
}
uint64_t BitConverter::ToUint64BE(uint8_t& b)
{
uint8_t* b2 = &b;
uint64_t v = 0;
v |= ((uint64_t)b2[0] << 56);
v |= ((uint64_t)b2[1] << 48);
v |= ((uint64_t)b2[2] << 40);
v |= ((uint64_t)b2[3] << 32);
v |= ((uint64_t)b2[4] << 24);
v |= ((uint64_t)b2[5] << 16);
v |= ((uint64_t)b2[6] << 8);
v |= (uint64_t)b2[7];
return v;
}
uint32_t BitConverter::ToUint32BE(uint8_t& b)
{
uint8_t* b2 = &b;
uint32_t v = 0;
v |= ((uint32_t)b2[0] << 24);
v |= ((uint32_t)b2[1] << 16);
v |= ((uint32_t)b2[2] << 8);
v |= (uint32_t)b2[3];
return v;
}
uint16_t BitConverter::ToUint16BE(uint8_t& b)
{
uint8_t* b2 = &b;
uint16_t v = 0;
v |= ((uint16_t)b2[0] << 8);
v |= (uint16_t)b2[1];
return v;
}
void BitConverter::FromDoubleBE(uint8_t& b, double v)
{
FromUint64BE(b,ToUintBits(v));
}
void BitConverter::FromUint64BE(uint8_t& b, uint64_t v)
{
uint8_t* b2 = &b;
b2[0] = (uint8_t)(v >> 56);
b2[1] = (uint8_t)(v >> 48);
b2[2] = (uint8_t)(v >> 40);
b2[3] = (uint8_t)(v >> 32);
b2[4] = (uint8_t)(v >> 24);
b2[5] = (uint8_t)(v >> 16);
b2[6] = (uint8_t)(v >> 8);
b2[7] = (uint8_t)v;
}
void BitConverter::FromUint32BE(uint8_t& b, uint32_t v)
{
uint8_t* b2 = &b;
b2[0] = (uint8_t)(v >> 24);
b2[1] = (uint8_t)(v >> 16);
b2[2] = (uint8_t)(v >> 8);
b2[3] = (uint8_t)v;
}
void BitConverter::FromUint16BE(uint8_t& b, uint16_t v)
{
uint8_t* b2 = &b;
b2[0] = (uint8_t)(v >> 8);
b2[1] = (uint8_t)v;
}
};

View File

@@ -4,6 +4,7 @@
#include <map>
#include <cstring>
#include <variant>
namespace Tesses::CrossLang
{
void Write(Tesses::Framework::Streams::Stream* strm, uint8_t* buffer, size_t len)

View File

@@ -220,10 +220,11 @@ namespace Tesses::CrossLang {
dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read);
dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine);
dict->DeclareFunction(gc,"Write","Write text \"text\" to stdout",{"text"},Console_Write);
dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"text"},Console_WriteLine);
dict->DeclareFunction(gc,"WriteLine","Write text \"text\" to stdout with new line",{"$text"},Console_WriteLine);
dict->DeclareFunction(gc,"Error", "Write text \"error\" to stderr",{"error"},Console_Error);
dict->DeclareFunction(gc,"ErrorLine","Write text \"error\" to stderr",{"error"},Console_ErrorLine);
dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal);
dict->DeclareFunction(gc,"ErrorLine","Write text \"error\" to stderr",{"$error"},Console_ErrorLine);
if(env->permissions.canRegisterEverything)
dict->DeclareFunction(gc,"Fatal","Stop the program with an optional error message",{"$text"},Console_Fatal);
dict->DeclareFunction(gc,"getIn","Get stdin Stream",{},Console_getIn);
dict->DeclareFunction(gc,"getOut","Get stdout Stream",{},Console_getOut);
dict->DeclareFunction(gc,"getError", "Get stderr Stream",{},Console_getError);

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,4 @@
#include "CrossLang.hpp"
#if defined(CROSSLANG_ENABLE_SHARED)
#if defined(CROSSLANG_ENABLE_FFI)
@@ -30,6 +31,35 @@
namespace Tesses::CrossLang
{
class TMuxex : public TNativeObject
{
public:
Tesses::Framework::Threading::Mutex mtx;
std::string TypeName()
{
return "Mutex";
}
TObject CallMethod(GCList& ls, std::string key, std::vector<TObject> args)
{
if(key == "Lock")
{
mtx.Lock();
}
else if(key == "Unlock")
{
mtx.Unlock();
}
else if(key == "TryLock")
{
return mtx.TryLock();
}
return Undefined();
}
};
class DocumentationParser : public TNativeObject
{
public:
@@ -1284,48 +1314,8 @@ namespace Tesses::CrossLang
return nullptr;
});
newTypes->DeclareFunction(gc, "Mutex", "Create mutex",{}, [](GCList& ls,std::vector<TObject> args)->TObject {
ls.GetGC()->BarrierBegin();
auto mtx = TDictionary::Create(ls);
auto native = TNative::Create(ls, new Tesses::Framework::Threading::Mutex(),[](void* ptr)->void{
delete static_cast<Tesses::Framework::Threading::Mutex*>(ptr);
});
auto lock = TExternalMethod::Create(ls,"Lock the mutex",{},[native](GCList& ls, std::vector<TObject> args)->TObject {
if(native->GetDestroyed()) return nullptr;
auto r = static_cast<Tesses::Framework::Threading::Mutex*>(native->GetPointer());
r->Lock();
return nullptr;
});
lock->watch.push_back(native);
mtx->SetValue("Lock",lock);
auto unlock = TExternalMethod::Create(ls,"Unlock the mutex",{},[native](GCList& ls, std::vector<TObject> args)->TObject {
if(native->GetDestroyed()) return nullptr;
auto r = static_cast<Tesses::Framework::Threading::Mutex*>(native->GetPointer());
r->Unlock();
return nullptr;
});
unlock->watch.push_back(native);
mtx->SetValue("Unlock",unlock);
auto trylock = TExternalMethod::Create(ls,"Try to lock the mutex, returns true if we aquire the lock, false if we can't due to another thread owning it",{},[native](GCList& ls, std::vector<TObject> args)->TObject {
if(native->GetDestroyed()) return true;
auto r = static_cast<Tesses::Framework::Threading::Mutex*>(native->GetPointer());
return r->TryLock();
});
trylock->watch.push_back(native);
mtx->SetValue("TryLock",trylock);
ls.GetGC()->BarrierEnd();
auto close = TExternalMethod::Create(ls,"Try to lock the mutex, returns true if we aquire the lock, false if we can't due to another thread owning it",{},[native](GCList& ls, std::vector<TObject> args)->TObject {
native->Destroy();
return nullptr;
});
close->watch.push_back(native);
mtx->SetValue("Close",close);
ls.GetGC()->BarrierEnd();
return mtx;
return TNativeObject::Create<TMuxex>(ls);
});
newTypes->DeclareFunction(gc, "Thread","Create thread",{"callback"},[](GCList& ls, std::vector<TObject> args)-> TObject
{

View File

@@ -8,6 +8,16 @@ namespace Tesses::CrossLang
for(auto& item : this->inherit_tree) type += " : " + item;
return type;
}
TObject TClassObject::CallMethod(GCList& ls, std::string className, std::string name,std::vector<TObject> args)
{
auto value = this->GetValue(className,name);
TCallable* callable;
if(GetObjectHeap(value, callable))
{
return callable->Call(ls,args);
}
return Undefined();
}
TClassObjectEntry* TClassObject::GetEntry(std::string classN, std::string key)
{
for(auto& item : this->entries)

View File

@@ -72,4 +72,4 @@ namespace Tesses::CrossLang
this->Destroy();
}
}
}

View File

@@ -1,3 +1,4 @@
#include "CrossLang.hpp"
#include <TessesFramework/Filesystem/VFS.hpp>
#include <cstddef>
@@ -3253,28 +3254,7 @@ namespace Tesses::CrossLang {
}
if(key == "Handle")
{
if(GetArgumentHeap(args,0,dict))
{
gc->BarrierBegin();
auto nat = dict->GetValue("native");
gc->BarrierEnd();
TNative* nat2;
if(GetObjectHeap(nat,nat2))
{
if(!nat2->GetDestroyed())
{
auto ctx = static_cast<Tesses::Framework::Http::ServerContext*>(nat2->GetPointer());
if(ctx != nullptr)
{
cse.back()->Push(gc,svr->server->Handle(*ctx));
return false;
}
}
}
}
cse.back()->Push(gc,false);
cse.back()->Push(gc,svr->Handle(args));
return false;
}
if(key == "Close")