Commit 68d7e4a1b6

Andrew Kelley <andrew@ziglang.org>
2019-04-13 22:53:53
better handle quota of setEvalBranchQuota
Now that c58b80203443dcbf8b737ebdaa1f17fb20c77711 has removed the "top of the comptime stack" requirement, the branch quota can be modified somewhere other than the top of the comptime stack. This means that the quota of a parent IrExecutable has to be modifiable by an instruction in the child. Closes #2261
1 parent a43fd7a
src/all_types.hpp
@@ -55,7 +55,7 @@ struct IrExecutable {
     size_t mem_slot_count;
     size_t next_debug_id;
     size_t *backward_branch_count;
-    size_t backward_branch_quota;
+    size_t *backward_branch_quota;
     ZigFn *fn_entry;
     Buf *c_import_buf;
     AstNode *source_node;
@@ -1350,6 +1350,7 @@ struct ZigFn {
     IrExecutable ir_executable;
     IrExecutable analyzed_executable;
     size_t prealloc_bbc;
+    size_t prealloc_backward_branch_quota;
     AstNode **param_source_nodes;
     Buf **param_names;
 
src/analyze.cpp
@@ -969,8 +969,9 @@ static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *no
         Buf *type_name)
 {
     size_t backward_branch_count = 0;
+    size_t backward_branch_quota = default_backward_branch_quota;
     return ir_eval_const_value(g, scope, node, type_entry,
-            &backward_branch_count, default_backward_branch_quota,
+            &backward_branch_count, &backward_branch_quota,
             nullptr, nullptr, node, type_name, nullptr, nullptr);
 }
 
@@ -2623,9 +2624,11 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld) {
 ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
     ZigFn *fn_entry = allocate<ZigFn>(1);
 
+    fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota;
+
     fn_entry->codegen = g;
     fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
-    fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;
+    fn_entry->analyzed_executable.backward_branch_quota = &fn_entry->prealloc_backward_branch_quota;
     fn_entry->analyzed_executable.fn_entry = fn_entry;
     fn_entry->ir_executable.fn_entry = fn_entry;
     fn_entry->fn_inline = inline_value;
src/ir.cpp
@@ -357,19 +357,9 @@ static void ir_ref_var(ZigVar *var) {
 }
 
 ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
-    ConstExprValue *result = ir_eval_const_value( ira->codegen
-                                                , scope
-                                                , node
-                                                , ira->codegen->builtin_types.entry_type
-                                                , ira->new_irb.exec->backward_branch_count
-                                                , ira->new_irb.exec->backward_branch_quota
-                                                , nullptr
-                                                , nullptr
-                                                , node
-                                                , nullptr
-                                                , ira->new_irb.exec
-                                                , nullptr
-                                                );
+    ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type,
+            ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr,
+            node, nullptr, ira->new_irb.exec, nullptr);
 
     if (type_is_invalid(result->type))
         return ira->codegen->builtin_types.entry_invalid;
@@ -7965,7 +7955,7 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec
             return &codegen->invalid_instruction->value;
         }
     }
-    return &codegen->invalid_instruction->value;
+    zig_unreachable();
 }
 
 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) {
@@ -10227,16 +10217,18 @@ static IrInstruction *ir_unreach_error(IrAnalyze *ira) {
 
 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) {
     size_t *bbc = ira->new_irb.exec->backward_branch_count;
-    size_t quota = ira->new_irb.exec->backward_branch_quota;
+    size_t *quota = ira->new_irb.exec->backward_branch_quota;
 
     // If we're already over quota, we've already given an error message for this.
-    if (*bbc > quota) {
+    if (*bbc > *quota) {
+        assert(ira->codegen->errors.length > 0);
         return false;
     }
 
     *bbc += 1;
-    if (*bbc > quota) {
-        ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota));
+    if (*bbc > *quota) {
+        ir_add_error(ira, source_instruction,
+                buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota));
         return false;
     }
     return true;
@@ -10317,7 +10309,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un
 }
 
 ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
-        ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
+        ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
         ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
         IrExecutable *parent_exec, AstNode *expected_type_source_node)
 {
@@ -18983,8 +18975,8 @@ static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ir
     if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota))
         return ira->codegen->invalid_instruction;
 
-    if (new_quota > ira->new_irb.exec->backward_branch_quota) {
-        ira->new_irb.exec->backward_branch_quota = new_quota;
+    if (new_quota > *ira->new_irb.exec->backward_branch_quota) {
+        *ira->new_irb.exec->backward_branch_quota = new_quota;
     }
 
     return ir_const_void(ira, &instruction->base);
src/ir.hpp
@@ -14,7 +14,7 @@ bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutable *ir_executable
 bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
 
 ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
-        ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
+        ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
         ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
         IrExecutable *parent_exec, AstNode *expected_type_source_node);