Skip to content

Commit

Permalink
cheerp: emit argument/environment variables initialization
Browse files Browse the repository at this point in the history
Emit global variables and their necessay initialization that can contain
program arguments/environment variables. These global variables are
string arrays.

Also add two builtins for internal use to get these globals:
void* __builtin_cheerp_environ(void);
void* __builtin_cheerp_argv(void);
  • Loading branch information
Hyxogen committed Jan 10, 2024
1 parent da47f30 commit 3824642
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 0 deletions.
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/BuiltinsCheerp.def
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ BUILTIN(__builtin_cheerp_throw, "", "rB")
BUILTIN(__builtin_cheerp_downcast, "", "B")
BUILTIN(__builtin_cheerp_downcast_current, "", "B")
BUILTIN(__builtin_cheerp_coro_alloc, "v*z", "n")
BUILTIN(__builtin_cheerp_environ, "vC*", "")
BUILTIN(__builtin_cheerp_argv, "vC*", "")

// SIMD builtins
TARGET_BUILTIN(__builtin_wasm_swizzle_i8x16, "V16ScV16ScV16Sc", "nc", "simd128")
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12506,6 +12506,16 @@ Value *CodeGenFunction::EmitCheerpBuiltinExpr(unsigned BuiltinID,
Function *F = CGM.getIntrinsic(Intrinsic::cheerp_grow_memory);
return Builder.CreateCall(F, Ops);
}
else if (BuiltinID == Cheerp::BI__builtin_cheerp_environ) {
llvm::Type *Tys[] = { ConvertType(E->getType()) };
Function *F = CGM.getIntrinsic(Intrinsic::cheerp_environ, Tys);
return Builder.CreateCall(F, Ops);
}
else if (BuiltinID == Cheerp::BI__builtin_cheerp_argv) {
llvm::Type *Tys[] = { ConvertType(E->getType()) };
Function *F = CGM.getIntrinsic(Intrinsic::cheerp_argv, Tys);
return Builder.CreateCall(F, Ops);
}
else if (BuiltinID == Cheerp::BI__builtin_cheerp_stack_save) {
Function *F = CGM.getIntrinsic(Intrinsic::stacksave);
return Builder.CreateCall(F, Ops);
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,11 @@ void cheerp::CheerpCompiler::ConstructJob(Compilation &C, const JobAction &JA,
}
}

CmdArgs.push_back("-cheerp-environ-name=CHEERP_ENV");
CmdArgs.push_back("-cheerp-reserved-names=CHEERP_ENV");
CmdArgs.push_back("-cheerp-argv-name=CHEERP_ARGV");
CmdArgs.push_back("-cheerp-reserved-names=CHEERP_ARGV");

if(Arg* cheerpSecondaryOutputFile = Args.getLastArg(options::OPT_cheerp_secondary_output_file_EQ))
cheerpSecondaryOutputFile->render(Args, CmdArgs);
else if(
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsCheerp.td
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ def int_cheerp_memory_init : Intrinsic<[llvm_i32_ty],
def int_cheerp_data_drop : Intrinsic<[llvm_i32_ty],
[llvm_i32_ty]>;

def int_cheerp_environ : Intrinsic<[llvm_anyptr_ty]>;

def int_cheerp_argv : Intrinsic<[llvm_anyptr_ty]>;

// SIMD left shift
def int_cheerp_wasm_shl : Intrinsic<[llvm_anyvector_ty],
[llvm_anyvector_ty, llvm_anyint_ty],
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/CheerpUtils/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,7 @@ llvm::cl::opt<bool> UseBigInts("cheerp-use-bigints", llvm::cl::desc("Use the Big
llvm::cl::opt<bool> KeepInvokes("cheerp-keep-invokes", llvm::cl::desc("Don't lower invokes to calls"));

llvm::cl::opt<bool> PreserveFree("cheerp-preserve-free", llvm::cl::desc("Don't optimize out calls to free"));
llvm::cl::opt<std::string> EnvironName("cheerp-environ-name", llvm::cl::Optional,
llvm::cl::desc("If specified, the identifier name storing the environment variables"), llvm::cl::value_desc("name"));
llvm::cl::opt<std::string> ArgvName("cheerp-argv-name", llvm::cl::Optional,
llvm::cl::desc("If specified, the identifier name storing the arguments"), llvm::cl::value_desc("name"));
3 changes: 3 additions & 0 deletions llvm/lib/CheerpUtils/PointerAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,9 @@ PointerKindWrapper& PointerUsageVisitor::visitValue(PointerKindWrapper& ret, con
isIntrinsic = true;
switch ( intrinsic->getIntrinsicID() )
{
case Intrinsic::cheerp_environ:
case Intrinsic::cheerp_argv:
break;
case Intrinsic::cheerp_virtualcast:
case Intrinsic::cheerp_downcast:
case Intrinsic::cheerp_upcast_collapsed:
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/CheerpWriter/CheerpWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ using namespace llvm;
using namespace std;
using namespace cheerp;

extern llvm::cl::opt<std::string> EnvironName;
extern llvm::cl::opt<std::string> ArgvName;

//De-comment this to debug the pointer kind of every function
//#define CHEERP_DEBUG_POINTERS

Expand Down Expand Up @@ -992,6 +995,16 @@ CheerpWriter::COMPILE_INSTRUCTION_FEEDBACK CheerpWriter::handleBuiltinCall(const
stream << "|0)|0";
return COMPILE_OK;
}
else if(intrinsicId==Intrinsic::cheerp_environ)
{
stream << EnvironName;
return COMPILE_OK;
}
else if(intrinsicId==Intrinsic::cheerp_argv)
{
stream << ArgvName;
return COMPILE_OK;
}
else if(intrinsicId==Intrinsic::abs)
{
//Implementing ( X >= 0 ) ? X : -X
Expand Down Expand Up @@ -6247,6 +6260,9 @@ void CheerpWriter::compileHelpers()
stream << "var " << namegen.getBuiltinName(NameGenerator::Builtin::STACKPTR) << '=' <<
linearHelper.getStackStart() << "|0;" << NewLine;
}

stream << "var " << EnvironName << "=[],";
stream << ArgvName << "=[];" << NewLine;
}

void CheerpWriter::compileImports()
Expand Down Expand Up @@ -6479,6 +6495,7 @@ void CheerpWriter::compileWasmLoader()
stream << getHeapName(i) << "=null,";
}
}

stream << "__asm=null,";
stream << "__heap=null;";
compileDummies();
Expand Down Expand Up @@ -6569,6 +6586,8 @@ void CheerpWriter::compileDeclareExports()
{
const std::string shortestName = namegen.getShortestLocalName();
stream << "export default function(" << shortestName << "){" << NewLine;
stream << EnvironName << "=" << shortestName << "?.env??[];" << NewLine;
stream << ArgvName << "=" << shortestName << "?.argv??[];" << NewLine;
stream << "return ";
}
else
Expand Down

0 comments on commit 3824642

Please sign in to comment.