diff --git a/clang/include/clang/Basic/BuiltinsCheerp.def b/clang/include/clang/Basic/BuiltinsCheerp.def index 8a5bb8af441e..f19fd7927695 100644 --- a/clang/include/clang/Basic/BuiltinsCheerp.def +++ b/clang/include/clang/Basic/BuiltinsCheerp.def @@ -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") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index c9376bce377a..06e45bd38b1f 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -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); diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp index 93563e0dd38f..e9e7cb1c11c7 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -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( diff --git a/llvm/include/llvm/IR/IntrinsicsCheerp.td b/llvm/include/llvm/IR/IntrinsicsCheerp.td index 8a8d8c90d7f5..b7687d9843cb 100644 --- a/llvm/include/llvm/IR/IntrinsicsCheerp.td +++ b/llvm/include/llvm/IR/IntrinsicsCheerp.td @@ -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], diff --git a/llvm/lib/CheerpUtils/CommandLine.cpp b/llvm/lib/CheerpUtils/CommandLine.cpp index ed2a58de95ca..0e8bfed0c991 100644 --- a/llvm/lib/CheerpUtils/CommandLine.cpp +++ b/llvm/lib/CheerpUtils/CommandLine.cpp @@ -91,3 +91,7 @@ llvm::cl::opt UseBigInts("cheerp-use-bigints", llvm::cl::desc("Use the Big llvm::cl::opt KeepInvokes("cheerp-keep-invokes", llvm::cl::desc("Don't lower invokes to calls")); llvm::cl::opt PreserveFree("cheerp-preserve-free", llvm::cl::desc("Don't optimize out calls to free")); +llvm::cl::opt 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 ArgvName("cheerp-argv-name", llvm::cl::Optional, + llvm::cl::desc("If specified, the identifier name storing the arguments"), llvm::cl::value_desc("name")); diff --git a/llvm/lib/CheerpUtils/PointerAnalyzer.cpp b/llvm/lib/CheerpUtils/PointerAnalyzer.cpp index 4e76bfe24803..d468cfc23c4b 100644 --- a/llvm/lib/CheerpUtils/PointerAnalyzer.cpp +++ b/llvm/lib/CheerpUtils/PointerAnalyzer.cpp @@ -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: diff --git a/llvm/lib/CheerpWriter/CheerpWriter.cpp b/llvm/lib/CheerpWriter/CheerpWriter.cpp index 77c826443857..c62b20493081 100644 --- a/llvm/lib/CheerpWriter/CheerpWriter.cpp +++ b/llvm/lib/CheerpWriter/CheerpWriter.cpp @@ -46,6 +46,9 @@ using namespace llvm; using namespace std; using namespace cheerp; +extern llvm::cl::opt EnvironName; +extern llvm::cl::opt ArgvName; + //De-comment this to debug the pointer kind of every function //#define CHEERP_DEBUG_POINTERS @@ -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 @@ -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() @@ -6479,6 +6495,7 @@ void CheerpWriter::compileWasmLoader() stream << getHeapName(i) << "=null,"; } } + stream << "__asm=null,"; stream << "__heap=null;"; compileDummies(); @@ -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