Browse Source

Add `@(no_red_zone)` for procedures

gingerBill 3 years ago
parent
commit
493bc653b5
5 changed files with 21 additions and 0 deletions
  1. 8 0
      src/check_decl.cpp
  2. 7 0
      src/checker.cpp
  3. 1 0
      src/checker.hpp
  4. 1 0
      src/entity.cpp
  5. 4 0
      src/llvm_backend_proc.cpp

+ 8 - 0
src/check_decl.cpp

@@ -826,6 +826,14 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 	}
 	e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode;
 
+	if (ac.no_red_zone) {
+		if (!is_arch_wasm()) {
+			e->Procedure.no_red_zone = true;
+		} else {
+			error(e->token, "@(no_red_zone) is not supported on this target architecture");
+		}
+	}
+
 	if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) {
 		if (ac.objc_name.len == 0 && ac.objc_is_class_method) {
 			error(e->token, "@(objc_name) is required with @(objc_is_class_method)");

+ 7 - 0
src/checker.cpp

@@ -3128,6 +3128,13 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
 			}
 		}
 		return true;
+	} else if (name == "no_red_zone") {
+		if (value != nullptr) {
+			error(elem, "Expected no value for '%.*s'", LIT(name));
+		} else {
+			ac->no_red_zone = true;
+		}
+		return true;
 	}
 	return false;
 }

+ 1 - 0
src/checker.hpp

@@ -117,6 +117,7 @@ struct AttributeContext {
 	bool    test                : 1;
 	bool    init                : 1;
 	bool    set_cold            : 1;
+	bool    no_red_zone         : 1;
 	u32 optimization_mode; // ProcedureOptimizationMode
 
 	String  objc_class;

+ 1 - 0
src/entity.cpp

@@ -226,6 +226,7 @@ struct Entity {
 			bool    is_foreign;
 			bool    is_export;
 			bool    generated_from_polymorphic;
+			bool    no_red_zone;
 			ProcedureOptimizationMode optimization_mode;
 		} Procedure;
 		struct {

+ 4 - 0
src/llvm_backend_proc.cpp

@@ -135,6 +135,10 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
 		lb_add_attribute_to_proc(m, p->value, "naked");
 	}
 
+	if (entity->Procedure.no_red_zone) {
+		lb_add_attribute_to_proc(m, p->value, "noredzone");
+	}
+
 	switch (p->inlining) {
 	case ProcInlining_inline:
 		lb_add_attribute_to_proc(m, p->value, "alwaysinline");