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,
1970619706 return ira->codegen->invalid_inst_gen;
1970719707 }
1970819708
19709 bool extern_fn_in_typeof = false;
19710
1970919711 if (modifier == CallModifierCompileTime) {
1971019712 // No special handling is needed for compile time evaluation of generic functions.
1971119713 if (!fn_entry || fn_entry->body_node == nullptr) {
19712 ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression"));
19713 return ira->codegen->invalid_inst_gen;
19714 // We keep evaluating extern functions in TypeOfs
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 }
1971419721 }
1971519722
1971619723 if (!ir_emit_backward_branch(ira, source_instr))
1971719724 return ira->codegen->invalid_inst_gen;
1971819725
1971919726 // 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
1972219730 size_t next_proto_i = 0;
1972319731 if (first_arg_ptr) {
......@@ -19766,7 +19774,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
1976619774 return_type = specified_return_type;
1976719775 }
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);
1977019778 ZigValue *result = nullptr;
1977119779 if (cacheable) {
1977219780 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,
1977919787 AstNode *body_node = fn_entry->body_node;
1978019788 ZigValue *result_ptr;
1978119789 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,
19783 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
19784 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node,
19785 UndefOk)))
19786 {
19787 return ira->codegen->invalid_inst_gen;
19790
19791 // If we are evaluating an extern function in a TypeOf, create a value and keep it undefined.
19792 if (!extern_fn_in_typeof) {
19793 if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr,
19794 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
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 }
1978819800 }
1978919801
1979019802 if (inferred_err_set_type != nullptr) {