authorgravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2020-04-27 02:33:21+03:00
committergravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2020-04-27 02:33:21+03:00
log179423ec2712956e04f188bf8b904e4fb9b48656
tree7cd09925e887291df1fce79c1c38ba902f0d650a
parentd44c9bdbd9c6add603997a834506ddd165a70cd4

Extern functions can now be evaluated to undefined values in TypeOfs


1 files changed, 22 insertions(+), 10 deletions(-)

src/ir.cpp+22-10
...@@ -19706,18 +19706,26 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -19706,18 +19706,26 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
19706 return ira->codegen->invalid_inst_gen;19706 return ira->codegen->invalid_inst_gen;
19707 }19707 }
1970819708
19709 bool extern_fn_in_typeof = false;
19710
19709 if (modifier == CallModifierCompileTime) {19711 if (modifier == CallModifierCompileTime) {
19710 // No special handling is needed for compile time evaluation of generic functions.19712 // No special handling is needed for compile time evaluation of generic functions.
19711 if (!fn_entry || fn_entry->body_node == nullptr) {19713 if (!fn_entry || fn_entry->body_node == nullptr) {
19712 ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression"));19714 // We keep evaluating extern functions in TypeOfs
19713 return ira->codegen->invalid_inst_gen;19715 if (get_scope_typeof(source_instr->scope) != nullptr && fn_entry) {
19716 extern_fn_in_typeof = true;
19717 } else {
19718 ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression"));
19719 return ira->codegen->invalid_inst_gen;
19720 }
19714 }19721 }
1971519722
19716 if (!ir_emit_backward_branch(ira, source_instr))19723 if (!ir_emit_backward_branch(ira, source_instr))
19717 return ira->codegen->invalid_inst_gen;19724 return ira->codegen->invalid_inst_gen;
1971819725
19719 // Fork a scope of the function with known values for the parameters.19726 // Fork a scope of the function with known values for the parameters.
19720 Scope *exec_scope = &fn_entry->fndef_scope->base;19727 // If we are evaluating an extern function in a TypeOf, we use the TypeOf's scope instead.
19728 Scope *exec_scope = extern_fn_in_typeof ? source_instr->scope : &fn_entry->fndef_scope->base;
1972119729
19722 size_t next_proto_i = 0;19730 size_t next_proto_i = 0;
19723 if (first_arg_ptr) {19731 if (first_arg_ptr) {
...@@ -19766,7 +19774,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -19766,7 +19774,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
19766 return_type = specified_return_type;19774 return_type = specified_return_type;
19767 }19775 }
1976819776
19769 bool cacheable = fn_eval_cacheable(exec_scope, return_type);19777 bool cacheable = !extern_fn_in_typeof && fn_eval_cacheable(exec_scope, return_type);
19770 ZigValue *result = nullptr;19778 ZigValue *result = nullptr;
19771 if (cacheable) {19779 if (cacheable) {
19772 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope);19780 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope);
...@@ -19779,12 +19787,16 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -19779,12 +19787,16 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
19779 AstNode *body_node = fn_entry->body_node;19787 AstNode *body_node = fn_entry->body_node;
19780 ZigValue *result_ptr;19788 ZigValue *result_ptr;
19781 create_result_ptr(ira->codegen, return_type, &result, &result_ptr);19789 create_result_ptr(ira->codegen, return_type, &result, &result_ptr);
19782 if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr,19790
19783 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,19791 // If we are evaluating an extern function in a TypeOf, create a value and keep it undefined.
19784 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node,19792 if (!extern_fn_in_typeof) {
19785 UndefOk)))19793 if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr,
19786 {19794 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
19787 return ira->codegen->invalid_inst_gen;19795 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node,
19796 UndefOk)))
19797 {
19798 return ira->codegen->invalid_inst_gen;
19799 }
19788 }19800 }
1978919801
19790 if (inferred_err_set_type != nullptr) {19802 if (inferred_err_set_type != nullptr) {