@@ -426,11 +426,11 @@ class CWriter {
426426 void WriteImportProperties (CWriterPhase);
427427 void WriteFuncs ();
428428 void BeginFunction (const Func&);
429- void FinishFunction ();
429+ void FinishFunction (size_t );
430430 void Write (const Func&);
431431 void WriteTailCallee (const Func&);
432432 void WriteParamsAndLocals ();
433- void WriteParams (const std::vector<std::string>& index_to_name);
433+ void WriteParams (const std::vector<std::string>& index_to_name, bool setjmp_safe = false );
434434 void WriteParamSymbols (const std::vector<std::string>& index_to_name);
435435 void WriteParamTypes (const FuncDeclaration& decl);
436436 void WriteLocals (const std::vector<std::string>& index_to_name);
@@ -444,7 +444,7 @@ class CWriter {
444444 void Unspill (const TypeVector&);
445445
446446 template <typename Vars, typename TypeOf, typename ToDo>
447- void WriteVarsByType (const Vars&, const TypeOf&, const ToDo&);
447+ void WriteVarsByType (const Vars&, const TypeOf&, const ToDo&, bool );
448448
449449 template <typename sources>
450450 void Spill (const TypeVector&, const sources& src);
@@ -3044,15 +3044,15 @@ void CWriter::BeginFunction(const Func& func) {
30443044 Write (Newline ());
30453045}
30463046
3047- void CWriter::FinishFunction () {
3047+ void CWriter::FinishFunction (size_t stack_var_section ) {
30483048 for (size_t i = 0 ; i < func_sections_.size (); ++i) {
30493049 auto & [condition, stream] = func_sections_.at (i);
30503050 std::unique_ptr<OutputBuffer> buf = stream.ReleaseOutputBuffer ();
30513051 if (condition.empty () || func_includes_.count (condition)) {
30523052 stream_->WriteData (buf->data .data (), buf->data .size ());
30533053 }
30543054
3055- if (i == 0 ) {
3055+ if (i == stack_var_section ) {
30563056 WriteStackVarDeclarations (); // these come immediately after section #0
30573057 // (return type/name/params/locals)
30583058 }
@@ -3072,6 +3072,7 @@ void CWriter::Write(const Func& func) {
30723072 WriteParamsAndLocals ();
30733073 Write (" FUNC_PROLOGUE;" , Newline ());
30743074
3075+ size_t stack_vars_section = func_sections_.size () - 1 ;
30753076 PushFuncSection ();
30763077
30773078 std::string label = DefineLabelName (kImplicitFuncLabel );
@@ -3095,13 +3096,14 @@ void CWriter::Write(const Func& func) {
30953096 }
30963097
30973098 stream_ = prev_stream;
3098- FinishFunction ();
3099+ FinishFunction (stack_vars_section );
30993100}
31003101
31013102template <typename Vars, typename TypeOf, typename ToDo>
31023103void CWriter::WriteVarsByType (const Vars& vars,
31033104 const TypeOf& typeoffunc,
3104- const ToDo& todo) {
3105+ const ToDo& todo,
3106+ bool setjmp_safe) {
31053107 for (Type type : {Type::I32, Type::I64, Type::F32, Type::F64, Type::V128,
31063108 Type::FuncRef, Type::ExternRef}) {
31073109 Index var_index = 0 ;
@@ -3110,6 +3112,11 @@ void CWriter::WriteVarsByType(const Vars& vars,
31103112 if (typeoffunc (var) == type) {
31113113 if (count == 0 ) {
31123114 Write (type, " " );
3115+ if (setjmp_safe) {
3116+ PushFuncSection (" exceptions" );
3117+ Write (" volatile " );
3118+ PushFuncSection ();
3119+ }
31133120 Indent (4 );
31143121 } else {
31153122 Write (" , " );
@@ -3145,14 +3152,15 @@ void CWriter::WriteTailCallee(const Func& func) {
31453152 if (func.GetNumParams ()) {
31463153 WriteVarsByType (
31473154 func.decl .sig .param_types , [](auto x) { return x; },
3148- [&](Index i, Type) { Write (DefineParamName (index_to_name[i])); });
3155+ [&](Index i, Type) { Write (DefineParamName (index_to_name[i])); }, true );
31493156 Write (OpenBrace (), func.decl .sig .param_types , " tmp;" , Newline (),
31503157 " wasm_rt_memcpy(&tmp, tail_call_stack, sizeof(tmp));" , Newline ());
31513158 Unspill (func.decl .sig .param_types ,
31523159 [&](auto i) { return ParamName (index_to_name[i]); });
31533160 Write (CloseBrace (), Newline ());
31543161 }
31553162
3163+ size_t stack_vars_section = func_sections_.size () - 1 ;
31563164 WriteLocals (index_to_name);
31573165
31583166 PushFuncSection ();
@@ -3176,19 +3184,19 @@ void CWriter::WriteTailCallee(const Func& func) {
31763184 Write (" next->fn = NULL;" , Newline ());
31773185
31783186 stream_ = prev_stream;
3179- FinishFunction ();
3187+ FinishFunction (stack_vars_section );
31803188}
31813189
31823190void CWriter::WriteParamsAndLocals () {
31833191 std::vector<std::string> index_to_name;
31843192 MakeTypeBindingReverseMapping (func_->GetNumParamsAndLocals (), func_->bindings ,
31853193 &index_to_name);
3186- WriteParams (index_to_name);
3194+ WriteParams (index_to_name, true );
31873195 Write (" " , OpenBrace ());
31883196 WriteLocals (index_to_name);
31893197}
31903198
3191- void CWriter::WriteParams (const std::vector<std::string>& index_to_name) {
3199+ void CWriter::WriteParams (const std::vector<std::string>& index_to_name, bool setjmp_safe ) {
31923200 Write (ModuleInstanceTypeName (), " * instance" );
31933201 if (func_->GetNumParams () != 0 ) {
31943202 Indent (4 );
@@ -3197,7 +3205,13 @@ void CWriter::WriteParams(const std::vector<std::string>& index_to_name) {
31973205 if (i != 0 && (i % 8 ) == 0 ) {
31983206 Write (Newline ());
31993207 }
3200- Write (func_->GetParamType (i), " " , DefineParamName (index_to_name[i]));
3208+ Write (func_->GetParamType (i), " " );
3209+ if (setjmp_safe) {
3210+ PushFuncSection (" exceptions" );
3211+ Write (" volatile " );
3212+ PushFuncSection ();
3213+ }
3214+ Write (DefineParamName (index_to_name[i]));
32013215 }
32023216 Dedent (4 );
32033217 }
@@ -3241,13 +3255,16 @@ void CWriter::WriteLocals(const std::vector<std::string>& index_to_name) {
32413255 } else {
32423256 Write (" 0" );
32433257 }
3244- });
3258+ }, true );
32453259}
32463260
32473261void CWriter::WriteStackVarDeclarations () {
3262+ // NOTE: setjmp_safe must be false, can't push func sections in here because
3263+ // this is called from FinishFunction.
3264+ // (luckily, we don't need setjmp_safe for these.)
32483265 WriteVarsByType (
32493266 stack_var_sym_map_, [](auto stp_name) { return stp_name.first .second ; },
3250- [&](Index, auto & stp_name) { Write (stp_name.second ); });
3267+ [&](Index, auto & stp_name) { Write (stp_name.second ); }, false );
32513268}
32523269
32533270void CWriter::Write (const Block& block) {
@@ -3263,6 +3280,7 @@ void CWriter::Write(const Block& block) {
32633280}
32643281
32653282size_t CWriter::BeginTry (const Block& block) {
3283+ func_includes_.insert (" exceptions" );
32663284 Write (OpenBrace ()); /* beginning of try-catch or try_table */
32673285 const std::string tlabel = DefineLabelName (block.label );
32683286 Write (" WASM_RT_UNWIND_TARGET *" , tlabel,
0 commit comments