mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Add em_asm funtionality
This commit is contained in:
parent
6bde23b75e
commit
eeea06a22b
2 changed files with 137 additions and 14 deletions
121
BeefLibs/corlib/src/WebAssembly.bf
Normal file
121
BeefLibs/corlib/src/WebAssembly.bf
Normal file
|
@ -0,0 +1,121 @@
|
|||
#if BF_PLATFORM_WASM
|
||||
|
||||
namespace System;
|
||||
|
||||
using System.Interop;
|
||||
|
||||
class WebAssembly
|
||||
{
|
||||
[CLink]
|
||||
private static extern int32 emscripten_asm_const_int(char8* code, char8* arg_sigs, ...);
|
||||
[CLink]
|
||||
private static extern void emscripten_asm_const_ptr(char8* code, char8* arg_sigs, ...);
|
||||
[CLink]
|
||||
private static extern double emscripten_asm_const_double(char8* code, char8* arg_sigs, ...);
|
||||
|
||||
[Intrinsic(":add_string_to_section")]
|
||||
private static extern char8* add_string_to_section(uint8* string, uint8* section);
|
||||
|
||||
private static Span<uint8> GetStringData(String value)
|
||||
{
|
||||
return StringView(value).ToRawData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string added to the specified data section.
|
||||
*/
|
||||
private static char8* AddStringToSection<T0, T1>(T0 value, T1 section) where T0 : const String where T1 : const String
|
||||
{
|
||||
static uint8[?] data = GetStringData(value);
|
||||
static uint8[?] sectionStr = GetStringData(section);
|
||||
|
||||
#unwarn
|
||||
return add_string_to_section(&data, §ionStr);
|
||||
}
|
||||
|
||||
private static void GetArgSigInternal(Type t, String s)
|
||||
{
|
||||
switch(t)
|
||||
{
|
||||
case typeof(float):
|
||||
s.Append('f');
|
||||
case typeof(double):
|
||||
s.Append('d');
|
||||
case typeof(c_ulong): fallthrough;
|
||||
case typeof(c_ulonglong):
|
||||
case typeof(c_longlong):
|
||||
case typeof(c_long):
|
||||
s.Append('j');
|
||||
default:
|
||||
#if BF_32_BIT
|
||||
s.Append('i');
|
||||
#else
|
||||
s.Append('p');
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[Comptime]
|
||||
static void JSGetArgSig(Type t, String s)
|
||||
{
|
||||
if(t.IsTuple)
|
||||
{
|
||||
int count = t.FieldCount;
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
var type = t.GetField(i).Get().FieldType;
|
||||
GetArgSigInternal(type, s);
|
||||
}
|
||||
}else
|
||||
GetArgSigInternal(t, s);
|
||||
}
|
||||
|
||||
private static String JSGetResultName(Type t)
|
||||
{
|
||||
if(t.IsPointer)
|
||||
return "ptr";
|
||||
else if (t.IsFloatingPoint)
|
||||
return "double";
|
||||
else
|
||||
return "int";
|
||||
}
|
||||
|
||||
[Comptime]
|
||||
private static void GetArgString<T>(String s)
|
||||
{
|
||||
Type type = typeof(T);
|
||||
int fieldCount = 0;
|
||||
if (type.IsTuple)
|
||||
{
|
||||
fieldCount = type.FieldCount;
|
||||
for(int i = 0; i< fieldCount; i++)
|
||||
{
|
||||
if(i == fieldCount-1)
|
||||
s.AppendF("p0.{}", i);
|
||||
else
|
||||
s.AppendF("p0.{}, ", i);
|
||||
}
|
||||
}
|
||||
else
|
||||
s.Append("p0");
|
||||
}
|
||||
|
||||
private static String JSGetCallString<TResult, TCall, T0>() where TCall : const String
|
||||
{
|
||||
if (TCall == null)
|
||||
return "";
|
||||
var argSigs = JSGetArgSig(typeof(T0), .. scope .());
|
||||
var argString = GetArgString<T0>(.. scope .());
|
||||
return new $"result = emscripten_asm_const_{JSGetResultName(typeof(TResult))}(AddStringToSection({TCall.Quote(.. scope .())}, \"em_asm\"), \"{argSigs}\", {argString});";
|
||||
}
|
||||
|
||||
public static TResult JSCall<TResult, TCall, T0>(TCall callString, T0 p0) where TCall : const String
|
||||
{
|
||||
TResult result = default;
|
||||
Compiler.Mixin(JSGetCallString<TResult, const TCall, T0>());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -3076,40 +3076,42 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
{
|
||||
case BfIRIntrinsic__PLATFORM:
|
||||
{
|
||||
if (intrinsicData->mName == "em_asm_internal")
|
||||
if (intrinsicData->mName == "add_string_to_section")
|
||||
{
|
||||
llvm::StringRef strContent;
|
||||
llvm::StringRef strContent[2];
|
||||
llvm::ConstantDataArray* dataArray;
|
||||
if (const llvm::ConstantExpr* ce = llvm::dyn_cast<llvm::ConstantExpr>(args[0]))
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
llvm::Value* firstOperand = ce->getOperand(0);
|
||||
if (llvm::GlobalVariable* gv = llvm::dyn_cast<llvm::GlobalVariable>(firstOperand))
|
||||
if (const llvm::ConstantExpr* ce = llvm::dyn_cast<llvm::ConstantExpr>(args[i]))
|
||||
{
|
||||
if (gv->getType()->isPointerTy())
|
||||
llvm::Value* firstOperand = ce->getOperand(0);
|
||||
if (llvm::GlobalVariable* gv = llvm::dyn_cast<llvm::GlobalVariable>(firstOperand))
|
||||
{
|
||||
if (dataArray = llvm::dyn_cast<llvm::ConstantDataArray>(gv->getInitializer()))
|
||||
if (gv->getType()->isPointerTy())
|
||||
{
|
||||
strContent = dataArray->getAsString();
|
||||
if (dataArray = llvm::dyn_cast<llvm::ConstantDataArray>(gv->getInitializer()))
|
||||
strContent[i] = dataArray->getAsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
FatalError("Value is not ConstantExpr");
|
||||
}
|
||||
else
|
||||
FatalError("Value is not ConstantExpr");
|
||||
|
||||
|
||||
auto charType = llvm::IntegerType::get(*mLLVMContext, 8);
|
||||
std::vector<llvm::Constant*> chars(strContent.size());
|
||||
for (unsigned int i = 0; i < strContent.size(); i++)
|
||||
std::vector<llvm::Constant*> chars(strContent[0].size());
|
||||
for (unsigned int i = 0; i < strContent[0].size(); i++)
|
||||
{
|
||||
chars[i] = llvm::ConstantInt::get(charType, strContent[i]);;
|
||||
chars[i] = llvm::ConstantInt::get(charType, strContent[0][i]);;
|
||||
}
|
||||
|
||||
chars.push_back(llvm::ConstantInt::get(charType, 0));
|
||||
auto stringType = llvm::ArrayType::get(charType, chars.size());
|
||||
|
||||
auto globalVar = (llvm::GlobalVariable*)mLLVMModule->getOrInsertGlobal("", stringType);
|
||||
globalVar->setSection("em_asm");
|
||||
globalVar->setSection(strContent[1]);
|
||||
globalVar->setInitializer(llvm::ConstantArray::get(stringType, chars));
|
||||
globalVar->setConstant(true);
|
||||
globalVar->setLinkage(llvm::GlobalValue::LinkageTypes::ExternalLinkage);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue