| ... | @@ -343,6 +343,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { | ... | @@ -343,6 +343,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { |
| 343 | return IrInstructionIdErrName; | 343 | return IrInstructionIdErrName; |
| 344 | } | 344 | } |
| 345 | | 345 | |
| | 346 | static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) { |
| | 347 | return IrInstructionIdEmbedFile; |
| | 348 | } |
| | 349 | |
| 346 | template<typename T> | 350 | template<typename T> |
| 347 | static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) { | 351 | static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) { |
| 348 | T *special_instruction = allocate<T>(1); | 352 | T *special_instruction = allocate<T>(1); |
| ... | @@ -1344,6 +1348,15 @@ static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *so | ... | @@ -1344,6 +1348,15 @@ static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *so |
| 1344 | return &instruction->base; | 1348 | return &instruction->base; |
| 1345 | } | 1349 | } |
| 1346 | | 1350 | |
| | 1351 | static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { |
| | 1352 | IrInstructionEmbedFile *instruction = ir_build_instruction<IrInstructionEmbedFile>(irb, scope, source_node); |
| | 1353 | instruction->name = name; |
| | 1354 | |
| | 1355 | ir_ref_instruction(name); |
| | 1356 | |
| | 1357 | return &instruction->base; |
| | 1358 | } |
| | 1359 | |
| 1347 | static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, | 1360 | static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, |
| 1348 | bool gen_error_defers, bool gen_maybe_defers) | 1361 | bool gen_error_defers, bool gen_maybe_defers) |
| 1349 | { | 1362 | { |
| ... | @@ -2074,6 +2087,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -2074,6 +2087,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 2074 | | 2087 | |
| 2075 | return ir_build_err_name(irb, scope, node, arg0_value); | 2088 | return ir_build_err_name(irb, scope, node, arg0_value); |
| 2076 | } | 2089 | } |
| | 2090 | case BuiltinFnIdEmbedFile: |
| | 2091 | { |
| | 2092 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| | 2093 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| | 2094 | if (arg0_value == irb->codegen->invalid_instruction) |
| | 2095 | return arg0_value; |
| | 2096 | |
| | 2097 | return ir_build_embed_file(irb, scope, node, arg0_value); |
| | 2098 | } |
| 2077 | case BuiltinFnIdMemcpy: | 2099 | case BuiltinFnIdMemcpy: |
| 2078 | case BuiltinFnIdMemset: | 2100 | case BuiltinFnIdMemset: |
| 2079 | case BuiltinFnIdAlignof: | 2101 | case BuiltinFnIdAlignof: |
| ... | @@ -2085,7 +2107,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -2085,7 +2107,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 2085 | case BuiltinFnIdBreakpoint: | 2107 | case BuiltinFnIdBreakpoint: |
| 2086 | case BuiltinFnIdReturnAddress: | 2108 | case BuiltinFnIdReturnAddress: |
| 2087 | case BuiltinFnIdFrameAddress: | 2109 | case BuiltinFnIdFrameAddress: |
| 2088 | case BuiltinFnIdEmbedFile: | | |
| 2089 | case BuiltinFnIdCmpExchange: | 2110 | case BuiltinFnIdCmpExchange: |
| 2090 | case BuiltinFnIdFence: | 2111 | case BuiltinFnIdFence: |
| 2091 | case BuiltinFnIdDivExact: | 2112 | case BuiltinFnIdDivExact: |
| ... | @@ -7141,6 +7162,45 @@ static TypeTableEntry *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstruct | ... | @@ -7141,6 +7162,45 @@ static TypeTableEntry *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstruct |
| 7141 | return ira->codegen->builtin_types.entry_void; | 7162 | return ira->codegen->builtin_types.entry_void; |
| 7142 | } | 7163 | } |
| 7143 | | 7164 | |
| | 7165 | static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionEmbedFile *instruction) { |
| | 7166 | IrInstruction *name = instruction->name->other; |
| | 7167 | if (name->type_entry->id == TypeTableEntryIdInvalid) |
| | 7168 | return ira->codegen->builtin_types.entry_invalid; |
| | 7169 | |
| | 7170 | Buf *rel_file_path = ir_resolve_str(ira, name); |
| | 7171 | if (!rel_file_path) |
| | 7172 | return ira->codegen->builtin_types.entry_invalid; |
| | 7173 | |
| | 7174 | ImportTableEntry *import = get_scope_import(instruction->base.scope); |
| | 7175 | // figure out absolute path to resource |
| | 7176 | Buf source_dir_path = BUF_INIT; |
| | 7177 | os_path_dirname(import->path, &source_dir_path); |
| | 7178 | |
| | 7179 | Buf file_path = BUF_INIT; |
| | 7180 | os_path_resolve(&source_dir_path, rel_file_path, &file_path); |
| | 7181 | |
| | 7182 | // load from file system into const expr |
| | 7183 | Buf file_contents = BUF_INIT; |
| | 7184 | int err; |
| | 7185 | if ((err = os_fetch_file_path(&file_path, &file_contents))) { |
| | 7186 | if (err == ErrorFileNotFound) { |
| | 7187 | ir_add_error(ira, &instruction->base, buf_sprintf("unable to find '%s'", buf_ptr(&file_path))); |
| | 7188 | return ira->codegen->builtin_types.entry_invalid; |
| | 7189 | } else { |
| | 7190 | ir_add_error(ira, &instruction->base, buf_sprintf("unable to open '%s': %s", buf_ptr(&file_path), err_str(err))); |
| | 7191 | return ira->codegen->builtin_types.entry_invalid; |
| | 7192 | } |
| | 7193 | } |
| | 7194 | |
| | 7195 | // TODO add dependency on the file we embedded so that we know if it changes |
| | 7196 | // we'll have to invalidate the cache |
| | 7197 | |
| | 7198 | bool depends_on_compile_var = true; |
| | 7199 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var); |
| | 7200 | init_const_str_lit(out_val,&file_contents); |
| | 7201 | |
| | 7202 | return get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(&file_contents)); |
| | 7203 | } |
| 7144 | | 7204 | |
| 7145 | | 7205 | |
| 7146 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 7206 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| ... | @@ -7243,6 +7303,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -7243,6 +7303,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 7243 | return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); | 7303 | return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); |
| 7244 | case IrInstructionIdCUndef: | 7304 | case IrInstructionIdCUndef: |
| 7245 | return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); | 7305 | return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); |
| | 7306 | case IrInstructionIdEmbedFile: |
| | 7307 | return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction); |
| 7246 | case IrInstructionIdCast: | 7308 | case IrInstructionIdCast: |
| 7247 | case IrInstructionIdStructFieldPtr: | 7309 | case IrInstructionIdStructFieldPtr: |
| 7248 | case IrInstructionIdEnumFieldPtr: | 7310 | case IrInstructionIdEnumFieldPtr: |
| ... | @@ -7377,6 +7439,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -7377,6 +7439,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7377 | case IrInstructionIdMinValue: | 7439 | case IrInstructionIdMinValue: |
| 7378 | case IrInstructionIdMaxValue: | 7440 | case IrInstructionIdMaxValue: |
| 7379 | case IrInstructionIdErrName: | 7441 | case IrInstructionIdErrName: |
| | 7442 | case IrInstructionIdEmbedFile: |
| 7380 | return false; | 7443 | return false; |
| 7381 | case IrInstructionIdAsm: | 7444 | case IrInstructionIdAsm: |
| 7382 | { | 7445 | { |
| ... | @@ -7390,45 +7453,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -7390,45 +7453,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7390 | // TODO port over all this commented out code into new IR way of doing things | 7453 | // TODO port over all this commented out code into new IR way of doing things |
| 7391 | | 7454 | |
| 7392 | | 7455 | |
| 7393 | //static TypeTableEntry *analyze_embed_file(CodeGen *g, ImportTableEntry *import, | | |
| 7394 | // BlockContext *context, AstNode *node) | | |
| 7395 | //{ | | |
| 7396 | // assert(node->type == NodeTypeFnCallExpr); | | |
| 7397 | // | | |
| 7398 | // AstNode **first_param_node = &node->data.fn_call_expr.params.at(0); | | |
| 7399 | // Buf *rel_file_path = resolve_const_expr_str(g, import, context, first_param_node); | | |
| 7400 | // if (!rel_file_path) { | | |
| 7401 | // return g->builtin_types.entry_invalid; | | |
| 7402 | // } | | |
| 7403 | // | | |
| 7404 | // // figure out absolute path to resource | | |
| 7405 | // Buf source_dir_path = BUF_INIT; | | |
| 7406 | // os_path_dirname(import->path, &source_dir_path); | | |
| 7407 | // | | |
| 7408 | // Buf file_path = BUF_INIT; | | |
| 7409 | // os_path_resolve(&source_dir_path, rel_file_path, &file_path); | | |
| 7410 | // | | |
| 7411 | // // load from file system into const expr | | |
| 7412 | // Buf file_contents = BUF_INIT; | | |
| 7413 | // int err; | | |
| 7414 | // if ((err = os_fetch_file_path(&file_path, &file_contents))) { | | |
| 7415 | // if (err == ErrorFileNotFound) { | | |
| 7416 | // add_node_error(g, node, | | |
| 7417 | // buf_sprintf("unable to find '%s'", buf_ptr(&file_path))); | | |
| 7418 | // return g->builtin_types.entry_invalid; | | |
| 7419 | // } else { | | |
| 7420 | // add_node_error(g, node, | | |
| 7421 | // buf_sprintf("unable to open '%s': %s", buf_ptr(&file_path), err_str(err))); | | |
| 7422 | // return g->builtin_types.entry_invalid; | | |
| 7423 | // } | | |
| 7424 | // } | | |
| 7425 | // | | |
| 7426 | // // TODO add dependency on the file we embedded so that we know if it changes | | |
| 7427 | // // we'll have to invalidate the cache | | |
| 7428 | // | | |
| 7429 | // return resolve_expr_const_val_as_string_lit(g, node, &file_contents); | | |
| 7430 | //} | | |
| 7431 | // | | |
| 7432 | //static TypeTableEntry *analyze_cmpxchg(CodeGen *g, ImportTableEntry *import, | 7456 | //static TypeTableEntry *analyze_cmpxchg(CodeGen *g, ImportTableEntry *import, |
| 7433 | // BlockContext *context, AstNode *node) | 7457 | // BlockContext *context, AstNode *node) |
| 7434 | //{ | 7458 | //{ |
| ... | @@ -7765,8 +7789,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -7765,8 +7789,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7765 | // case BuiltinFnIdFrameAddress: | 7789 | // case BuiltinFnIdFrameAddress: |
| 7766 | // mark_impure_fn(g, context, node); | 7790 | // mark_impure_fn(g, context, node); |
| 7767 | // return builtin_fn->return_type; | 7791 | // return builtin_fn->return_type; |
| 7768 | // case BuiltinFnIdEmbedFile: | | |
| 7769 | // return analyze_embed_file(g, import, context, node); | | |
| 7770 | // case BuiltinFnIdCmpExchange: | 7792 | // case BuiltinFnIdCmpExchange: |
| 7771 | // return analyze_cmpxchg(g, import, context, node); | 7793 | // return analyze_cmpxchg(g, import, context, node); |
| 7772 | // case BuiltinFnIdFence: | 7794 | // case BuiltinFnIdFence: |
| ... | @@ -8353,7 +8375,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -8353,7 +8375,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 8353 | // case BuiltinFnIdMinValue: | 8375 | // case BuiltinFnIdMinValue: |
| 8354 | // case BuiltinFnIdMaxValue: | 8376 | // case BuiltinFnIdMaxValue: |
| 8355 | // case BuiltinFnIdMemberCount: | 8377 | // case BuiltinFnIdMemberCount: |
| 8356 | // case BuiltinFnIdEmbedFile: | | |
| 8357 | // // caught by constant expression eval codegen | 8378 | // // caught by constant expression eval codegen |
| 8358 | // zig_unreachable(); | 8379 | // zig_unreachable(); |
| 8359 | // case BuiltinFnIdCompileVar: | 8380 | // case BuiltinFnIdCompileVar: |