Commit 10cea15cc3
Changed files (4)
src/all_types.hpp
@@ -1406,6 +1406,7 @@ enum IrInstructionId {
IrInstructionIdMaxValue,
IrInstructionIdCompileErr,
IrInstructionIdErrName,
+ IrInstructionIdEmbedFile,
};
struct IrInstruction {
@@ -1852,6 +1853,12 @@ struct IrInstructionCUndef {
IrInstruction *name;
};
+struct IrInstructionEmbedFile {
+ IrInstruction base;
+
+ IrInstruction *name;
+};
+
enum LValPurpose {
LValPurposeNone,
LValPurposeAssign,
src/codegen.cpp
@@ -1878,6 +1878,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdCInclude:
case IrInstructionIdCDefine:
case IrInstructionIdCUndef:
+ case IrInstructionIdEmbedFile:
zig_unreachable();
case IrInstructionIdReturn:
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
src/ir.cpp
@@ -343,6 +343,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) {
return IrInstructionIdErrName;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) {
+ return IrInstructionIdEmbedFile;
+}
+
template<typename T>
static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate<T>(1);
@@ -1344,6 +1348,15 @@ static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *so
return &instruction->base;
}
+static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) {
+ IrInstructionEmbedFile *instruction = ir_build_instruction<IrInstructionEmbedFile>(irb, scope, source_node);
+ instruction->name = name;
+
+ ir_ref_instruction(name);
+
+ return &instruction->base;
+}
+
static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,
bool gen_error_defers, bool gen_maybe_defers)
{
@@ -2074,6 +2087,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
return ir_build_err_name(irb, scope, node, arg0_value);
}
+ case BuiltinFnIdEmbedFile:
+ {
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
+ if (arg0_value == irb->codegen->invalid_instruction)
+ return arg0_value;
+
+ return ir_build_embed_file(irb, scope, node, arg0_value);
+ }
case BuiltinFnIdMemcpy:
case BuiltinFnIdMemset:
case BuiltinFnIdAlignof:
@@ -2085,7 +2107,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
case BuiltinFnIdBreakpoint:
case BuiltinFnIdReturnAddress:
case BuiltinFnIdFrameAddress:
- case BuiltinFnIdEmbedFile:
case BuiltinFnIdCmpExchange:
case BuiltinFnIdFence:
case BuiltinFnIdDivExact:
@@ -7141,6 +7162,45 @@ static TypeTableEntry *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstruct
return ira->codegen->builtin_types.entry_void;
}
+static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionEmbedFile *instruction) {
+ IrInstruction *name = instruction->name->other;
+ if (name->type_entry->id == TypeTableEntryIdInvalid)
+ return ira->codegen->builtin_types.entry_invalid;
+
+ Buf *rel_file_path = ir_resolve_str(ira, name);
+ if (!rel_file_path)
+ return ira->codegen->builtin_types.entry_invalid;
+
+ ImportTableEntry *import = get_scope_import(instruction->base.scope);
+ // figure out absolute path to resource
+ Buf source_dir_path = BUF_INIT;
+ os_path_dirname(import->path, &source_dir_path);
+
+ Buf file_path = BUF_INIT;
+ os_path_resolve(&source_dir_path, rel_file_path, &file_path);
+
+ // load from file system into const expr
+ Buf file_contents = BUF_INIT;
+ int err;
+ if ((err = os_fetch_file_path(&file_path, &file_contents))) {
+ if (err == ErrorFileNotFound) {
+ ir_add_error(ira, &instruction->base, buf_sprintf("unable to find '%s'", buf_ptr(&file_path)));
+ return ira->codegen->builtin_types.entry_invalid;
+ } else {
+ ir_add_error(ira, &instruction->base, buf_sprintf("unable to open '%s': %s", buf_ptr(&file_path), err_str(err)));
+ return ira->codegen->builtin_types.entry_invalid;
+ }
+ }
+
+ // TODO add dependency on the file we embedded so that we know if it changes
+ // we'll have to invalidate the cache
+
+ bool depends_on_compile_var = true;
+ ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var);
+ init_const_str_lit(out_val,&file_contents);
+
+ return get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(&file_contents));
+}
static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
@@ -7243,6 +7303,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction);
case IrInstructionIdCUndef:
return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction);
+ case IrInstructionIdEmbedFile:
+ return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction);
case IrInstructionIdCast:
case IrInstructionIdStructFieldPtr:
case IrInstructionIdEnumFieldPtr:
@@ -7377,6 +7439,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdMinValue:
case IrInstructionIdMaxValue:
case IrInstructionIdErrName:
+ case IrInstructionIdEmbedFile:
return false;
case IrInstructionIdAsm:
{
@@ -7390,45 +7453,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
// TODO port over all this commented out code into new IR way of doing things
-//static TypeTableEntry *analyze_embed_file(CodeGen *g, ImportTableEntry *import,
-// BlockContext *context, AstNode *node)
-//{
-// assert(node->type == NodeTypeFnCallExpr);
-//
-// AstNode **first_param_node = &node->data.fn_call_expr.params.at(0);
-// Buf *rel_file_path = resolve_const_expr_str(g, import, context, first_param_node);
-// if (!rel_file_path) {
-// return g->builtin_types.entry_invalid;
-// }
-//
-// // figure out absolute path to resource
-// Buf source_dir_path = BUF_INIT;
-// os_path_dirname(import->path, &source_dir_path);
-//
-// Buf file_path = BUF_INIT;
-// os_path_resolve(&source_dir_path, rel_file_path, &file_path);
-//
-// // load from file system into const expr
-// Buf file_contents = BUF_INIT;
-// int err;
-// if ((err = os_fetch_file_path(&file_path, &file_contents))) {
-// if (err == ErrorFileNotFound) {
-// add_node_error(g, node,
-// buf_sprintf("unable to find '%s'", buf_ptr(&file_path)));
-// return g->builtin_types.entry_invalid;
-// } else {
-// add_node_error(g, node,
-// buf_sprintf("unable to open '%s': %s", buf_ptr(&file_path), err_str(err)));
-// return g->builtin_types.entry_invalid;
-// }
-// }
-//
-// // TODO add dependency on the file we embedded so that we know if it changes
-// // we'll have to invalidate the cache
-//
-// return resolve_expr_const_val_as_string_lit(g, node, &file_contents);
-//}
-//
//static TypeTableEntry *analyze_cmpxchg(CodeGen *g, ImportTableEntry *import,
// BlockContext *context, AstNode *node)
//{
@@ -7765,8 +7789,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
// case BuiltinFnIdFrameAddress:
// mark_impure_fn(g, context, node);
// return builtin_fn->return_type;
-// case BuiltinFnIdEmbedFile:
-// return analyze_embed_file(g, import, context, node);
// case BuiltinFnIdCmpExchange:
// return analyze_cmpxchg(g, import, context, node);
// case BuiltinFnIdFence:
@@ -8353,7 +8375,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
// case BuiltinFnIdMinValue:
// case BuiltinFnIdMaxValue:
// case BuiltinFnIdMemberCount:
-// case BuiltinFnIdEmbedFile:
// // caught by constant expression eval codegen
// zig_unreachable();
// case BuiltinFnIdCompileVar:
src/ir_print.cpp
@@ -713,6 +713,12 @@ static void ir_print_c_undef(IrPrint *irp, IrInstructionCUndef *instruction) {
fprintf(irp->f, ")");
}
+static void ir_print_embed_file(IrPrint *irp, IrInstructionEmbedFile *instruction) {
+ fprintf(irp->f, "@embedFile(");
+ ir_print_other_instruction(irp, instruction->name);
+ fprintf(irp->f, ")");
+}
+
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
ir_print_prefix(irp, instruction);
switch (instruction->id) {
@@ -874,6 +880,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdCUndef:
ir_print_c_undef(irp, (IrInstructionCUndef *)instruction);
break;
+ case IrInstructionIdEmbedFile:
+ ir_print_embed_file(irp, (IrInstructionEmbedFile *)instruction);
+ break;
}
fprintf(irp->f, "\n");
}