| author | |
| committer | |
| log | 3ca027ca8219dbdbb6467645944c4daada037f51 |
| tree | 786a6c4ecac9f11d3a60f3c14c1b4276a3adc8d6 |
| parent | 536c35136ab98f2f56d07937727b3c99c0e35c5c |
* `zig build --export [obj|lib|exe]` changed to `zig build_obj`,
`zig build_lib` and `zig build_exe` respectively.
* `--name` parameter is optional when it can be inferred from the
root source filename. closes #207
* `zig build` now looks for `build.zig` which interacts with
`std.build.Builder` to describe the targets, and then the zig
build system prints TODO: build these targets. See #204
* add `@bitcast` which is mainly used for pointer reinterpret
casting and make explicit casting not do pointer reinterpretation.
Closes #290
* fix debug info for byval parameters
* sort command line help options
* `std.debug.panic` supports format string printing
* add `std.mem.IncrementingAllocator`
* fix const ptr to a variable with data changing at runtime.
closes #28927 files changed, 475 insertions(+), 188 deletions(-)
CMakeLists.txt+2| ... | @@ -204,6 +204,7 @@ install(TARGETS zig DESTINATION bin) | ... | @@ -204,6 +204,7 @@ install(TARGETS zig DESTINATION bin) |
| 204 | 204 | ||
| 205 | install(FILES ${C_HEADERS} DESTINATION ${C_HEADERS_DEST}) | 205 | install(FILES ${C_HEADERS} DESTINATION ${C_HEADERS_DEST}) |
| 206 | 206 | ||
| 207 | install(FILES "${CMAKE_SOURCE_DIR}/std/build.zig" DESTINATION "${ZIG_STD_DEST}") | ||
| 207 | install(FILES "${CMAKE_SOURCE_DIR}/std/c/darwin.zig" DESTINATION "${ZIG_STD_DEST}/c") | 208 | install(FILES "${CMAKE_SOURCE_DIR}/std/c/darwin.zig" DESTINATION "${ZIG_STD_DEST}/c") |
| 208 | install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST}/c") | 209 | install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST}/c") |
| 209 | install(FILES "${CMAKE_SOURCE_DIR}/std/c/linux.zig" DESTINATION "${ZIG_STD_DEST}/c") | 210 | install(FILES "${CMAKE_SOURCE_DIR}/std/c/linux.zig" DESTINATION "${ZIG_STD_DEST}/c") |
| ... | @@ -234,6 +235,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") | ... | @@ -234,6 +235,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") |
| 234 | install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}") | 235 | install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}") |
| 235 | install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}") | 236 | install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}") |
| 236 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special") | 237 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 238 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") | ||
| 237 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") | 239 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 238 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special") | 240 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 239 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") | 241 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") |
README.md+2-3| ... | @@ -82,13 +82,12 @@ the Zig compiler itself: | ... | @@ -82,13 +82,12 @@ the Zig compiler itself: |
| 82 | * gcc >= 5.0.0 or clang >= 3.6.0 | 82 | * gcc >= 5.0.0 or clang >= 3.6.0 |
| 83 | * cmake >= 2.8.5 | 83 | * cmake >= 2.8.5 |
| 84 | 84 | ||
| 85 | #### Runtime Dependencies | 85 | #### Library Dependencies |
| 86 | 86 | ||
| 87 | These libraries must be installed on your system, with the development files | 87 | These libraries must be installed on your system, with the development files |
| 88 | available. The Zig compiler dynamically links against them. | 88 | available. The Zig compiler dynamically links against them. |
| 89 | 89 | ||
| 90 | * LLVM == 4.x | 90 | * LLVM, Clang, and LLD libraries == 4.x |
| 91 | * libclang == 4.x | ||
| 92 | 91 | ||
| 93 | ### Debug / Development Build | 92 | ### Debug / Development Build |
| 94 | 93 |
doc/langref.md+7| ... | @@ -633,3 +633,10 @@ Invokes the panic handler function. By default the panic handler function | ... | @@ -633,3 +633,10 @@ Invokes the panic handler function. By default the panic handler function |
| 633 | calls the public `panic` function exposed in the root source file, or | 633 | calls the public `panic` function exposed in the root source file, or |
| 634 | if there is not one specified, invokes the one provided in | 634 | if there is not one specified, invokes the one provided in |
| 635 | `std/special/panic.zig`. | 635 | `std/special/panic.zig`. |
| 636 | |||
| 637 | ### @bitcast(comptime DestType: type, value: var) -> DestType | ||
| 638 | |||
| 639 | Transmutes memory from one type to another without changing any bits. | ||
| 640 | The source and destination types must have the same size. This function | ||
| 641 | can be used to, for example, reinterpret a pointer, or convert a `f32` to a | ||
| 642 | `u32`. |
src/all_types.hpp+5-3| ... | @@ -1196,6 +1196,7 @@ enum BuiltinFnId { | ... | @@ -1196,6 +1196,7 @@ enum BuiltinFnId { |
| 1196 | BuiltinFnIdSetGlobalSection, | 1196 | BuiltinFnIdSetGlobalSection, |
| 1197 | BuiltinFnIdSetGlobalLinkage, | 1197 | BuiltinFnIdSetGlobalLinkage, |
| 1198 | BuiltinFnIdPanic, | 1198 | BuiltinFnIdPanic, |
| 1199 | BuiltinFnIdBitCast, | ||
| 1199 | }; | 1200 | }; |
| 1200 | 1201 | ||
| 1201 | struct BuiltinFnEntry { | 1202 | struct BuiltinFnEntry { |
| ... | @@ -1719,7 +1720,7 @@ enum IrInstructionId { | ... | @@ -1719,7 +1720,7 @@ enum IrInstructionId { |
| 1719 | IrInstructionIdFnProto, | 1720 | IrInstructionIdFnProto, |
| 1720 | IrInstructionIdTestComptime, | 1721 | IrInstructionIdTestComptime, |
| 1721 | IrInstructionIdInitEnum, | 1722 | IrInstructionIdInitEnum, |
| 1722 | IrInstructionIdPointerReinterpret, | 1723 | IrInstructionIdBitCast, |
| 1723 | IrInstructionIdWidenOrShorten, | 1724 | IrInstructionIdWidenOrShorten, |
| 1724 | IrInstructionIdIntToPtr, | 1725 | IrInstructionIdIntToPtr, |
| 1725 | IrInstructionIdPtrToInt, | 1726 | IrInstructionIdPtrToInt, |
| ... | @@ -2369,10 +2370,11 @@ struct IrInstructionInitEnum { | ... | @@ -2369,10 +2370,11 @@ struct IrInstructionInitEnum { |
| 2369 | LLVMValueRef tmp_ptr; | 2370 | LLVMValueRef tmp_ptr; |
| 2370 | }; | 2371 | }; |
| 2371 | 2372 | ||
| 2372 | struct IrInstructionPointerReinterpret { | 2373 | struct IrInstructionBitCast { |
| 2373 | IrInstruction base; | 2374 | IrInstruction base; |
| 2374 | 2375 | ||
| 2375 | IrInstruction *ptr; | 2376 | IrInstruction *dest_type; |
| 2377 | IrInstruction *target; | ||
| 2376 | }; | 2378 | }; |
| 2377 | 2379 | ||
| 2378 | struct IrInstructionWidenOrShorten { | 2380 | struct IrInstructionWidenOrShorten { |
src/analyze.cpp+1-1| ... | @@ -3355,7 +3355,6 @@ bool type_has_bits(TypeTableEntry *type_entry) { | ... | @@ -3355,7 +3355,6 @@ bool type_has_bits(TypeTableEntry *type_entry) { |
| 3355 | bool type_requires_comptime(TypeTableEntry *type_entry) { | 3355 | bool type_requires_comptime(TypeTableEntry *type_entry) { |
| 3356 | switch (get_underlying_type(type_entry)->id) { | 3356 | switch (get_underlying_type(type_entry)->id) { |
| 3357 | case TypeTableEntryIdInvalid: | 3357 | case TypeTableEntryIdInvalid: |
| 3358 | case TypeTableEntryIdUnreachable: | ||
| 3359 | case TypeTableEntryIdVar: | 3358 | case TypeTableEntryIdVar: |
| 3360 | case TypeTableEntryIdTypeDecl: | 3359 | case TypeTableEntryIdTypeDecl: |
| 3361 | zig_unreachable(); | 3360 | zig_unreachable(); |
| ... | @@ -3383,6 +3382,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) { | ... | @@ -3383,6 +3382,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) { |
| 3383 | case TypeTableEntryIdPointer: | 3382 | case TypeTableEntryIdPointer: |
| 3384 | case TypeTableEntryIdEnumTag: | 3383 | case TypeTableEntryIdEnumTag: |
| 3385 | case TypeTableEntryIdVoid: | 3384 | case TypeTableEntryIdVoid: |
| 3385 | case TypeTableEntryIdUnreachable: | ||
| 3386 | return false; | 3386 | return false; |
| 3387 | } | 3387 | } |
| 3388 | zig_unreachable(); | 3388 | zig_unreachable(); |
src/codegen.cpp+15-8| ... | @@ -47,7 +47,7 @@ static void init_darwin_native(CodeGen *g) { | ... | @@ -47,7 +47,7 @@ static void init_darwin_native(CodeGen *g) { |
| 47 | } | 47 | } |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path) { | 50 | PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path) { |
| 51 | PackageTableEntry *entry = allocate<PackageTableEntry>(1); | 51 | PackageTableEntry *entry = allocate<PackageTableEntry>(1); |
| 52 | entry->package_table.init(4); | 52 | entry->package_table.init(4); |
| 53 | buf_init_from_str(&entry->root_src_dir, root_src_dir); | 53 | buf_init_from_str(&entry->root_src_dir, root_src_dir); |
| ... | @@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, | ... | @@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, |
| 1345 | zig_unreachable(); | 1345 | zig_unreachable(); |
| 1346 | } | 1346 | } |
| 1347 | 1347 | ||
| 1348 | static LLVMValueRef ir_render_pointer_reinterpret(CodeGen *g, IrExecutable *executable, | 1348 | static LLVMValueRef ir_render_bitcast(CodeGen *g, IrExecutable *executable, |
| 1349 | IrInstructionPointerReinterpret *instruction) | 1349 | IrInstructionBitCast *instruction) |
| 1350 | { | 1350 | { |
| 1351 | TypeTableEntry *wanted_type = instruction->base.value.type; | 1351 | TypeTableEntry *wanted_type = instruction->base.value.type; |
| 1352 | LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); | 1352 | LLVMValueRef target = ir_llvm_value(g, instruction->target); |
| 1353 | return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, ""); | 1353 | return LLVMBuildBitCast(g->builder, target, wanted_type->type_ref, ""); |
| 1354 | } | 1354 | } |
| 1355 | 1355 | ||
| 1356 | static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable, | 1356 | static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable, |
| ... | @@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 2776 | return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction); | 2776 | return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction); |
| 2777 | case IrInstructionIdStructInit: | 2777 | case IrInstructionIdStructInit: |
| 2778 | return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction); | 2778 | return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction); |
| 2779 | case IrInstructionIdPointerReinterpret: | 2779 | case IrInstructionIdBitCast: |
| 2780 | return ir_render_pointer_reinterpret(g, executable, (IrInstructionPointerReinterpret *)instruction); | 2780 | return ir_render_bitcast(g, executable, (IrInstructionBitCast *)instruction); |
| 2781 | case IrInstructionIdWidenOrShorten: | 2781 | case IrInstructionIdWidenOrShorten: |
| 2782 | return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction); | 2782 | return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction); |
| 2783 | case IrInstructionIdPtrToInt: | 2783 | case IrInstructionIdPtrToInt: |
| ... | @@ -3638,8 +3638,14 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -3638,8 +3638,14 @@ static void do_code_gen(CodeGen *g) { |
| 3638 | } else { | 3638 | } else { |
| 3639 | assert(var->gen_arg_index != SIZE_MAX); | 3639 | assert(var->gen_arg_index != SIZE_MAX); |
| 3640 | TypeTableEntry *gen_type; | 3640 | TypeTableEntry *gen_type; |
| 3641 | FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index]; | ||
| 3642 | |||
| 3641 | if (handle_is_ptr(var->value->type)) { | 3643 | if (handle_is_ptr(var->value->type)) { |
| 3642 | gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type; | 3644 | if (gen_info->is_byval) { |
| 3645 | gen_type = var->value->type; | ||
| 3646 | } else { | ||
| 3647 | gen_type = gen_info->type; | ||
| 3648 | } | ||
| 3643 | var->value_ref = LLVMGetParam(fn, var->gen_arg_index); | 3649 | var->value_ref = LLVMGetParam(fn, var->gen_arg_index); |
| 3644 | } else { | 3650 | } else { |
| 3645 | gen_type = var->value->type; | 3651 | gen_type = var->value->type; |
| ... | @@ -4254,6 +4260,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -4254,6 +4260,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4254 | create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2); | 4260 | create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2); |
| 4255 | create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2); | 4261 | create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2); |
| 4256 | create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); | 4262 | create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); |
| 4263 | create_builtin_fn(g, BuiltinFnIdBitCast, "bitcast", 2); | ||
| 4257 | } | 4264 | } |
| 4258 | 4265 | ||
| 4259 | static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) { | 4266 | static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) { |
src/codegen.hpp+1| ... | @@ -45,6 +45,7 @@ void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min); | ... | @@ -45,6 +45,7 @@ void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min); |
| 45 | void codegen_set_linker_script(CodeGen *g, const char *linker_script); | 45 | void codegen_set_linker_script(CodeGen *g, const char *linker_script); |
| 46 | void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt); | 46 | void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt); |
| 47 | 47 | ||
| 48 | PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path); | ||
| 48 | void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code); | 49 | void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code); |
| 49 | 50 | ||
| 50 | void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code); | 51 | void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code); |
src/ir.cpp+76-59| ... | @@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) { | ... | @@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) { |
| 480 | return IrInstructionIdInitEnum; | 480 | return IrInstructionIdInitEnum; |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | static constexpr IrInstructionId ir_instruction_id(IrInstructionPointerReinterpret *) { | 483 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { |
| 484 | return IrInstructionIdPointerReinterpret; | 484 | return IrInstructionIdBitCast; |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { | 487 | static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { |
| ... | @@ -1940,14 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old | ... | @@ -1940,14 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old |
| 1940 | return new_instruction; | 1940 | return new_instruction; |
| 1941 | } | 1941 | } |
| 1942 | 1942 | ||
| 1943 | static IrInstruction *ir_build_pointer_reinterpret(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1943 | static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1944 | IrInstruction *ptr) | 1944 | IrInstruction *dest_type, IrInstruction *target) |
| 1945 | { | 1945 | { |
| 1946 | IrInstructionPointerReinterpret *instruction = ir_build_instruction<IrInstructionPointerReinterpret>( | 1946 | IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( |
| 1947 | irb, scope, source_node); | 1947 | irb, scope, source_node); |
| 1948 | instruction->ptr = ptr; | 1948 | instruction->dest_type = dest_type; |
| 1949 | instruction->target = target; | ||
| 1949 | 1950 | ||
| 1950 | ir_ref_instruction(ptr, irb->current_basic_block); | 1951 | if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); |
| 1952 | ir_ref_instruction(target, irb->current_basic_block); | ||
| 1951 | 1953 | ||
| 1952 | return &instruction->base; | 1954 | return &instruction->base; |
| 1953 | } | 1955 | } |
| ... | @@ -2664,11 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins | ... | @@ -2664,11 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins |
| 2664 | } | 2666 | } |
| 2665 | } | 2667 | } |
| 2666 | 2668 | ||
| 2667 | static IrInstruction *ir_instruction_pointerreinterpret_get_dep(IrInstructionPointerReinterpret *instruction, | 2669 | static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction, |
| 2668 | size_t index) | 2670 | size_t index) |
| 2669 | { | 2671 | { |
| 2670 | switch (index) { | 2672 | switch (index) { |
| 2671 | case 0: return instruction->ptr; | 2673 | case 0: return instruction->dest_type; |
| 2674 | case 1: return instruction->target; | ||
| 2672 | default: return nullptr; | 2675 | default: return nullptr; |
| 2673 | } | 2676 | } |
| 2674 | } | 2677 | } |
| ... | @@ -2925,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t | ... | @@ -2925,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 2925 | return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index); | 2928 | return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index); |
| 2926 | case IrInstructionIdInitEnum: | 2929 | case IrInstructionIdInitEnum: |
| 2927 | return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index); | 2930 | return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index); |
| 2928 | case IrInstructionIdPointerReinterpret: | 2931 | case IrInstructionIdBitCast: |
| 2929 | return ir_instruction_pointerreinterpret_get_dep((IrInstructionPointerReinterpret *) instruction, index); | 2932 | return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index); |
| 2930 | case IrInstructionIdWidenOrShorten: | 2933 | case IrInstructionIdWidenOrShorten: |
| 2931 | return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index); | 2934 | return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index); |
| 2932 | case IrInstructionIdIntToPtr: | 2935 | case IrInstructionIdIntToPtr: |
| ... | @@ -4197,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4197,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4197 | 4200 | ||
| 4198 | return ir_build_panic(irb, scope, node, arg0_value); | 4201 | return ir_build_panic(irb, scope, node, arg0_value); |
| 4199 | } | 4202 | } |
| 4203 | case BuiltinFnIdBitCast: | ||
| 4204 | { | ||
| 4205 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4206 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4207 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4208 | return arg0_value; | ||
| 4209 | |||
| 4210 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4211 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4212 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4213 | return arg1_value; | ||
| 4214 | |||
| 4215 | return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value); | ||
| 4216 | } | ||
| 4200 | } | 4217 | } |
| 4201 | zig_unreachable(); | 4218 | zig_unreachable(); |
| 4202 | } | 4219 | } |
| ... | @@ -6364,34 +6381,6 @@ static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *sourc | ... | @@ -6364,34 +6381,6 @@ static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *sourc |
| 6364 | return result; | 6381 | return result; |
| 6365 | } | 6382 | } |
| 6366 | 6383 | ||
| 6367 | static IrInstruction *ir_analyze_pointer_reinterpret(IrAnalyze *ira, IrInstruction *source_instr, | ||
| 6368 | IrInstruction *ptr, TypeTableEntry *wanted_type) | ||
| 6369 | { | ||
| 6370 | if (ptr->value.type->id != TypeTableEntryIdPointer && | ||
| 6371 | ptr->value.type->id != TypeTableEntryIdMaybe) | ||
| 6372 | { | ||
| 6373 | ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&ptr->value.type->name))); | ||
| 6374 | return ira->codegen->invalid_instruction; | ||
| 6375 | } | ||
| 6376 | |||
| 6377 | if (instr_is_comptime(ptr)) { | ||
| 6378 | ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk); | ||
| 6379 | if (!val) | ||
| 6380 | return ira->codegen->invalid_instruction; | ||
| 6381 | |||
| 6382 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | ||
| 6383 | source_instr->scope, source_instr->source_node); | ||
| 6384 | const_instruction->base.value = *val; | ||
| 6385 | const_instruction->base.value.type = wanted_type; | ||
| 6386 | return &const_instruction->base; | ||
| 6387 | } | ||
| 6388 | |||
| 6389 | IrInstruction *result = ir_build_pointer_reinterpret(&ira->new_irb, source_instr->scope, | ||
| 6390 | source_instr->source_node, ptr); | ||
| 6391 | result->value.type = wanted_type; | ||
| 6392 | return result; | ||
| 6393 | } | ||
| 6394 | |||
| 6395 | static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, | 6384 | static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 6396 | IrInstruction *value, TypeTableEntry *wanted_type) | 6385 | IrInstruction *value, TypeTableEntry *wanted_type) |
| 6397 | { | 6386 | { |
| ... | @@ -6829,24 +6818,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -6829,24 +6818,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 6829 | } | 6818 | } |
| 6830 | } | 6819 | } |
| 6831 | 6820 | ||
| 6832 | // explicit cast from pointer to another pointer | ||
| 6833 | if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) && | ||
| 6834 | (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn)) | ||
| 6835 | { | ||
| 6836 | return ir_analyze_pointer_reinterpret(ira, source_instr, value, wanted_type); | ||
| 6837 | } | ||
| 6838 | |||
| 6839 | // explicit cast from maybe pointer to another maybe pointer | ||
| 6840 | if (actual_type->id == TypeTableEntryIdMaybe && | ||
| 6841 | (actual_type->data.maybe.child_type->id == TypeTableEntryIdPointer || | ||
| 6842 | actual_type->data.maybe.child_type->id == TypeTableEntryIdFn) && | ||
| 6843 | wanted_type->id == TypeTableEntryIdMaybe && | ||
| 6844 | (wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer || | ||
| 6845 | wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn)) | ||
| 6846 | { | ||
| 6847 | return ir_analyze_pointer_reinterpret(ira, source_instr, value, wanted_type); | ||
| 6848 | } | ||
| 6849 | |||
| 6850 | // explicit cast from child type of maybe type to maybe type | 6821 | // explicit cast from child type of maybe type to maybe type |
| 6851 | if (wanted_type->id == TypeTableEntryIdMaybe) { | 6822 | if (wanted_type->id == TypeTableEntryIdMaybe) { |
| 6852 | if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) { | 6823 | if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) { |
| ... | @@ -8986,6 +8957,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -8986,6 +8957,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 8986 | 8957 | ||
| 8987 | ConstExprValue *array_ptr_val; | 8958 | ConstExprValue *array_ptr_val; |
| 8988 | if (array_ptr->value.special != ConstValSpecialRuntime && | 8959 | if (array_ptr->value.special != ConstValSpecialRuntime && |
| 8960 | array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar && | ||
| 8989 | (array_ptr_val = const_ptr_pointee(&array_ptr->value)) && | 8961 | (array_ptr_val = const_ptr_pointee(&array_ptr->value)) && |
| 8990 | array_ptr_val->special != ConstValSpecialRuntime && | 8962 | array_ptr_val->special != ConstValSpecialRuntime && |
| 8991 | (array_type->id != TypeTableEntryIdPointer || | 8963 | (array_type->id != TypeTableEntryIdPointer || |
| ... | @@ -12210,6 +12182,50 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio | ... | @@ -12210,6 +12182,50 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio |
| 12210 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); | 12182 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 12211 | } | 12183 | } |
| 12212 | 12184 | ||
| 12185 | static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { | ||
| 12186 | IrInstruction *dest_type_value = instruction->dest_type->other; | ||
| 12187 | TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value); | ||
| 12188 | if (type_is_invalid(dest_type)) | ||
| 12189 | return ira->codegen->builtin_types.entry_invalid; | ||
| 12190 | |||
| 12191 | IrInstruction *target = instruction->target->other; | ||
| 12192 | TypeTableEntry *src_type = target->value.type; | ||
| 12193 | if (type_is_invalid(src_type)) | ||
| 12194 | return ira->codegen->builtin_types.entry_invalid; | ||
| 12195 | |||
| 12196 | ensure_complete_type(ira->codegen, dest_type); | ||
| 12197 | ensure_complete_type(ira->codegen, src_type); | ||
| 12198 | |||
| 12199 | uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); | ||
| 12200 | uint64_t src_size_bytes = type_size(ira->codegen, src_type); | ||
| 12201 | if (dest_size_bytes != src_size_bytes) { | ||
| 12202 | ir_add_error(ira, &instruction->base, | ||
| 12203 | buf_sprintf("destination type '%s' has size %" PRIu64 " but source type '%s' has size %" PRIu64, | ||
| 12204 | buf_ptr(&dest_type->name), dest_size_bytes, | ||
| 12205 | buf_ptr(&src_type->name), src_size_bytes)); | ||
| 12206 | return ira->codegen->builtin_types.entry_invalid; | ||
| 12207 | } | ||
| 12208 | |||
| 12209 | if (instr_is_comptime(target) && src_type->id == dest_type->id && | ||
| 12210 | (src_type->id == TypeTableEntryIdPointer || src_type->id == TypeTableEntryIdMaybe)) | ||
| 12211 | { | ||
| 12212 | ConstExprValue *val = ir_resolve_const(ira, target, UndefOk); | ||
| 12213 | if (!val) | ||
| 12214 | return ira->codegen->builtin_types.entry_invalid; | ||
| 12215 | |||
| 12216 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | ||
| 12217 | *out_val = *val; | ||
| 12218 | out_val->type = dest_type; | ||
| 12219 | return dest_type; | ||
| 12220 | } | ||
| 12221 | |||
| 12222 | IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope, | ||
| 12223 | instruction->base.source_node, nullptr, target); | ||
| 12224 | ir_link_new_instruction(result, &instruction->base); | ||
| 12225 | result->value.type = dest_type; | ||
| 12226 | return dest_type; | ||
| 12227 | } | ||
| 12228 | |||
| 12213 | static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira, | 12229 | static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 12214 | IrInstructionDeclRef *instruction) | 12230 | IrInstructionDeclRef *instruction) |
| 12215 | { | 12231 | { |
| ... | @@ -12283,7 +12299,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira, | ... | @@ -12283,7 +12299,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 12283 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 12299 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 12284 | switch (instruction->id) { | 12300 | switch (instruction->id) { |
| 12285 | case IrInstructionIdInvalid: | 12301 | case IrInstructionIdInvalid: |
| 12286 | case IrInstructionIdPointerReinterpret: | ||
| 12287 | case IrInstructionIdWidenOrShorten: | 12302 | case IrInstructionIdWidenOrShorten: |
| 12288 | case IrInstructionIdIntToPtr: | 12303 | case IrInstructionIdIntToPtr: |
| 12289 | case IrInstructionIdPtrToInt: | 12304 | case IrInstructionIdPtrToInt: |
| ... | @@ -12449,6 +12464,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -12449,6 +12464,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 12449 | return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); | 12464 | return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); |
| 12450 | case IrInstructionIdPanic: | 12465 | case IrInstructionIdPanic: |
| 12451 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); | 12466 | return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); |
| 12467 | case IrInstructionIdBitCast: | ||
| 12468 | return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); | ||
| 12452 | case IrInstructionIdMaybeWrap: | 12469 | case IrInstructionIdMaybeWrap: |
| 12453 | case IrInstructionIdErrWrapCode: | 12470 | case IrInstructionIdErrWrapCode: |
| 12454 | case IrInstructionIdErrWrapPayload: | 12471 | case IrInstructionIdErrWrapPayload: |
| ... | @@ -12620,7 +12637,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -12620,7 +12637,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 12620 | case IrInstructionIdFnProto: | 12637 | case IrInstructionIdFnProto: |
| 12621 | case IrInstructionIdTestComptime: | 12638 | case IrInstructionIdTestComptime: |
| 12622 | case IrInstructionIdInitEnum: | 12639 | case IrInstructionIdInitEnum: |
| 12623 | case IrInstructionIdPointerReinterpret: | 12640 | case IrInstructionIdBitCast: |
| 12624 | case IrInstructionIdWidenOrShorten: | 12641 | case IrInstructionIdWidenOrShorten: |
| 12625 | case IrInstructionIdPtrToInt: | 12642 | case IrInstructionIdPtrToInt: |
| 12626 | case IrInstructionIdIntToPtr: | 12643 | case IrInstructionIdIntToPtr: |
src/ir_print.cpp+5-5| ... | @@ -765,9 +765,9 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction) | ... | @@ -765,9 +765,9 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction) |
| 765 | fprintf(irp->f, "}"); | 765 | fprintf(irp->f, "}"); |
| 766 | } | 766 | } |
| 767 | 767 | ||
| 768 | static void ir_print_pointer_reinterpret(IrPrint *irp, IrInstructionPointerReinterpret *instruction) { | 768 | static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) { |
| 769 | fprintf(irp->f, "@pointerReinterpret("); | 769 | fprintf(irp->f, "@bitcast("); |
| 770 | ir_print_other_instruction(irp, instruction->ptr); | 770 | ir_print_other_instruction(irp, instruction->target); |
| 771 | fprintf(irp->f, ")"); | 771 | fprintf(irp->f, ")"); |
| 772 | } | 772 | } |
| 773 | 773 | ||
| ... | @@ -1098,8 +1098,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1098,8 +1098,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1098 | case IrInstructionIdInitEnum: | 1098 | case IrInstructionIdInitEnum: |
| 1099 | ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction); | 1099 | ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction); |
| 1100 | break; | 1100 | break; |
| 1101 | case IrInstructionIdPointerReinterpret: | 1101 | case IrInstructionIdBitCast: |
| 1102 | ir_print_pointer_reinterpret(irp, (IrInstructionPointerReinterpret *)instruction); | 1102 | ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction); |
| 1103 | break; | 1103 | break; |
| 1104 | case IrInstructionIdWidenOrShorten: | 1104 | case IrInstructionIdWidenOrShorten: |
| 1105 | ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction); | 1105 | ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction); |
src/main.cpp+110-52| ... | @@ -19,46 +19,48 @@ | ... | @@ -19,46 +19,48 @@ |
| 19 | static int usage(const char *arg0) { | 19 | static int usage(const char *arg0) { |
| 20 | fprintf(stderr, "Usage: %s [command] [options]\n" | 20 | fprintf(stderr, "Usage: %s [command] [options]\n" |
| 21 | "Commands:\n" | 21 | "Commands:\n" |
| 22 | " build [sources] create executable, object, or library from source\n" | 22 | " build build project from build.zig\n" |
| 23 | " test [sources] create and run a test build\n" | 23 | " build_exe [source] create executable from source\n" |
| 24 | " build_lib [source] create library from source\n" | ||
| 25 | " build_obj [source] create object from source\n" | ||
| 24 | " parseh [source] convert a c header file to zig extern declarations\n" | 26 | " parseh [source] convert a c header file to zig extern declarations\n" |
| 25 | " version print version number and exit\n" | ||
| 26 | " targets list available compilation targets\n" | 27 | " targets list available compilation targets\n" |
| 28 | " test [source] create and run a test build\n" | ||
| 29 | " version print version number and exit\n" | ||
| 27 | "Options:\n" | 30 | "Options:\n" |
| 28 | " --release build with optimizations on and debug protection off\n" | 31 | " --ar-path [path] set the path to ar\n" |
| 29 | " --static output will be statically linked\n" | ||
| 30 | " --strip exclude debug symbols\n" | ||
| 31 | " --export [exe|lib|obj] override output type\n" | ||
| 32 | " --name [name] override output name\n" | ||
| 33 | " --output [file] override destination path\n" | ||
| 34 | " --verbose turn on compiler debug output\n" | ||
| 35 | " --color [auto|off|on] enable or disable colored error messages\n" | 32 | " --color [auto|off|on] enable or disable colored error messages\n" |
| 36 | " --libc-lib-dir [path] directory where libc crt1.o resides\n" | ||
| 37 | " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n" | ||
| 38 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" | ||
| 39 | " --zig-std-dir [path] directory where zig standard library resides\n" | ||
| 40 | " --dynamic-linker [path] set the path to ld.so\n" | 33 | " --dynamic-linker [path] set the path to ld.so\n" |
| 34 | " --each-lib-rpath add rpath for each used dynamic library\n" | ||
| 41 | " --ld-path [path] set the path to the linker\n" | 35 | " --ld-path [path] set the path to the linker\n" |
| 42 | " --ar-path [path] set the path to ar\n" | 36 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| 43 | " -isystem [dir] add additional search path for other .h files\n" | 37 | " --libc-lib-dir [path] directory where libc crt1.o resides\n" |
| 44 | " -dirafter [dir] same as -isystem but do it last\n" | 38 | " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n" |
| 45 | " --library-path [dir] add a directory to the library search path\n" | ||
| 46 | " -L[dir] alias for --library-path\n" | ||
| 47 | " --library [lib] link against lib\n" | 39 | " --library [lib] link against lib\n" |
| 40 | " --library-path [dir] add a directory to the library search path\n" | ||
| 41 | " --linker-script [path] use a custom linker script\n" | ||
| 42 | " --name [name] override output name\n" | ||
| 43 | " --output [file] override destination path\n" | ||
| 44 | " --release build with optimizations on and debug protection off\n" | ||
| 45 | " --static output will be statically linked\n" | ||
| 46 | " --strip exclude debug symbols\n" | ||
| 48 | " --target-arch [name] specify target architecture\n" | 47 | " --target-arch [name] specify target architecture\n" |
| 49 | " --target-os [name] specify target operating system\n" | ||
| 50 | " --target-environ [name] specify target environment\n" | 48 | " --target-environ [name] specify target environment\n" |
| 51 | " -mwindows (windows only) --subsystem windows to the linker\n" | 49 | " --target-os [name] specify target operating system\n" |
| 50 | " --verbose turn on compiler debug output\n" | ||
| 51 | " --zig-std-dir [path] directory where zig standard library resides\n" | ||
| 52 | " -L[dir] alias for --library-path\n" | ||
| 53 | " -dirafter [dir] same as -isystem but do it last\n" | ||
| 54 | " -framework [name] (darwin only) link against framework\n" | ||
| 55 | " -isystem [dir] add additional search path for other .h files\n" | ||
| 52 | " -mconsole (windows only) --subsystem console to the linker\n" | 56 | " -mconsole (windows only) --subsystem console to the linker\n" |
| 53 | " -municode (windows only) link with unicode\n" | 57 | " -mios-version-min [ver] (darwin only) set iOS deployment target\n" |
| 54 | " -mlinker-version [ver] (darwin only) override linker version\n" | 58 | " -mlinker-version [ver] (darwin only) override linker version\n" |
| 55 | " -rdynamic add all symbols to the dynamic symbol table\n" | ||
| 56 | " -mmacosx-version-min [ver] (darwin only) set Mac OS X deployment target\n" | 59 | " -mmacosx-version-min [ver] (darwin only) set Mac OS X deployment target\n" |
| 57 | " -mios-version-min [ver] (darwin only) set iOS deployment target\n" | 60 | " -municode (windows only) link with unicode\n" |
| 58 | " -framework [name] (darwin only) link against framework\n" | 61 | " -mwindows (windows only) --subsystem windows to the linker\n" |
| 59 | " --linker-script [path] use a custom linker script\n" | 62 | " -rdynamic add all symbols to the dynamic symbol table\n" |
| 60 | " -rpath [path] add directory to the runtime library search path\n" | 63 | " -rpath [path] add directory to the runtime library search path\n" |
| 61 | " --each-lib-rpath add rpath for each used dynamic library\n" | ||
| 62 | , arg0); | 64 | , arg0); |
| 63 | return EXIT_FAILURE; | 65 | return EXIT_FAILURE; |
| 64 | } | 66 | } |
| ... | @@ -144,6 +146,62 @@ int main(int argc, char **argv) { | ... | @@ -144,6 +146,62 @@ int main(int argc, char **argv) { |
| 144 | ZigList<const char *> rpath_list = {0}; | 146 | ZigList<const char *> rpath_list = {0}; |
| 145 | bool each_lib_rpath = false; | 147 | bool each_lib_rpath = false; |
| 146 | 148 | ||
| 149 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { | ||
| 150 | const char *zig_exe_path = arg0; | ||
| 151 | |||
| 152 | init_all_targets(); | ||
| 153 | |||
| 154 | Buf *zig_std_dir = buf_create_from_str(ZIG_STD_DIR); | ||
| 155 | Buf *special_dir = buf_alloc(); | ||
| 156 | os_path_join(zig_std_dir, buf_sprintf("special"), special_dir); | ||
| 157 | |||
| 158 | Buf *build_runner_path = buf_alloc(); | ||
| 159 | os_path_join(special_dir, buf_create_from_str("build_runner.zig"), build_runner_path); | ||
| 160 | |||
| 161 | ZigList<const char *> args = {0}; | ||
| 162 | args.append(zig_exe_path); | ||
| 163 | for (int i = 2; i < argc; i += 1) { | ||
| 164 | if (strcmp(argv[i], "--verbose") == 0) { | ||
| 165 | verbose = true; | ||
| 166 | args.append(argv[i]); | ||
| 167 | } else { | ||
| 168 | args.append(argv[i]); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | |||
| 173 | Buf root_source_dir = BUF_INIT; | ||
| 174 | Buf root_source_code = BUF_INIT; | ||
| 175 | Buf root_source_name = BUF_INIT; | ||
| 176 | os_path_split(build_runner_path, &root_source_dir, &root_source_name); | ||
| 177 | if ((err = os_fetch_file_path(build_runner_path, &root_source_code))) { | ||
| 178 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(build_runner_path), err_str(err)); | ||
| 179 | return 1; | ||
| 180 | } | ||
| 181 | CodeGen *g = codegen_create(&root_source_dir, nullptr); | ||
| 182 | codegen_set_out_name(g, buf_create_from_str("build")); | ||
| 183 | codegen_set_out_type(g, OutTypeExe); | ||
| 184 | codegen_set_verbose(g, verbose); | ||
| 185 | |||
| 186 | PackageTableEntry *build_pkg = new_package(".", "build.zig"); | ||
| 187 | build_pkg->package_table.put(buf_create_from_str("std"), g->std_package); | ||
| 188 | g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg); | ||
| 189 | codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code); | ||
| 190 | codegen_link(g, "build"); | ||
| 191 | |||
| 192 | Termination term; | ||
| 193 | os_spawn_process("./build", args, &term); | ||
| 194 | if (term.how != TerminationIdClean || term.code != 0) { | ||
| 195 | fprintf(stderr, "\nBuild failed. Use the following command to reproduce the failure:\n"); | ||
| 196 | fprintf(stderr, "./build"); | ||
| 197 | for (size_t i = 0; i < args.length; i += 1) { | ||
| 198 | fprintf(stderr, " \"%s\"", args.at(i)); | ||
| 199 | } | ||
| 200 | fprintf(stderr, "\n"); | ||
| 201 | } | ||
| 202 | return (term.how == TerminationIdClean) ? term.code : -1; | ||
| 203 | } | ||
| 204 | |||
| 147 | for (int i = 1; i < argc; i += 1) { | 205 | for (int i = 1; i < argc; i += 1) { |
| 148 | char *arg = argv[i]; | 206 | char *arg = argv[i]; |
| 149 | 207 | ||
| ... | @@ -177,16 +235,6 @@ int main(int argc, char **argv) { | ... | @@ -177,16 +235,6 @@ int main(int argc, char **argv) { |
| 177 | return usage(arg0); | 235 | return usage(arg0); |
| 178 | } else if (strcmp(arg, "--output") == 0) { | 236 | } else if (strcmp(arg, "--output") == 0) { |
| 179 | out_file = argv[i]; | 237 | out_file = argv[i]; |
| 180 | } else if (strcmp(arg, "--export") == 0) { | ||
| 181 | if (strcmp(argv[i], "exe") == 0) { | ||
| 182 | out_type = OutTypeExe; | ||
| 183 | } else if (strcmp(argv[i], "lib") == 0) { | ||
| 184 | out_type = OutTypeLib; | ||
| 185 | } else if (strcmp(argv[i], "obj") == 0) { | ||
| 186 | out_type = OutTypeObj; | ||
| 187 | } else { | ||
| 188 | return usage(arg0); | ||
| 189 | } | ||
| 190 | } else if (strcmp(arg, "--color") == 0) { | 238 | } else if (strcmp(arg, "--color") == 0) { |
| 191 | if (strcmp(argv[i], "auto") == 0) { | 239 | if (strcmp(argv[i], "auto") == 0) { |
| 192 | color = ErrColorAuto; | 240 | color = ErrColorAuto; |
| ... | @@ -243,8 +291,15 @@ int main(int argc, char **argv) { | ... | @@ -243,8 +291,15 @@ int main(int argc, char **argv) { |
| 243 | } | 291 | } |
| 244 | } | 292 | } |
| 245 | } else if (cmd == CmdInvalid) { | 293 | } else if (cmd == CmdInvalid) { |
| 246 | if (strcmp(arg, "build") == 0) { | 294 | if (strcmp(arg, "build_exe") == 0) { |
| 295 | cmd = CmdBuild; | ||
| 296 | out_type = OutTypeExe; | ||
| 297 | } else if (strcmp(arg, "build_obj") == 0) { | ||
| 247 | cmd = CmdBuild; | 298 | cmd = CmdBuild; |
| 299 | out_type = OutTypeObj; | ||
| 300 | } else if (strcmp(arg, "build_lib") == 0) { | ||
| 301 | cmd = CmdBuild; | ||
| 302 | out_type = OutTypeLib; | ||
| 248 | } else if (strcmp(arg, "version") == 0) { | 303 | } else if (strcmp(arg, "version") == 0) { |
| 249 | cmd = CmdVersion; | 304 | cmd = CmdVersion; |
| 250 | } else if (strcmp(arg, "parseh") == 0) { | 305 | } else if (strcmp(arg, "parseh") == 0) { |
| ... | @@ -285,15 +340,7 @@ int main(int argc, char **argv) { | ... | @@ -285,15 +340,7 @@ int main(int argc, char **argv) { |
| 285 | if (!in_file) | 340 | if (!in_file) |
| 286 | return usage(arg0); | 341 | return usage(arg0); |
| 287 | 342 | ||
| 288 | if (cmd == CmdBuild && !out_name) { | 343 | assert(cmd != CmdBuild || out_type != OutTypeUnknown); |
| 289 | fprintf(stderr, "--name [name] not provided\n\n"); | ||
| 290 | return usage(arg0); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (cmd == CmdBuild && out_type == OutTypeUnknown) { | ||
| 294 | fprintf(stderr, "--export [exe|lib|obj] not provided\n\n"); | ||
| 295 | return usage(arg0); | ||
| 296 | } | ||
| 297 | 344 | ||
| 298 | init_all_targets(); | 345 | init_all_targets(); |
| 299 | 346 | ||
| ... | @@ -331,6 +378,9 @@ int main(int argc, char **argv) { | ... | @@ -331,6 +378,9 @@ int main(int argc, char **argv) { |
| 331 | Buf root_source_dir = BUF_INIT; | 378 | Buf root_source_dir = BUF_INIT; |
| 332 | Buf root_source_code = BUF_INIT; | 379 | Buf root_source_code = BUF_INIT; |
| 333 | Buf root_source_name = BUF_INIT; | 380 | Buf root_source_name = BUF_INIT; |
| 381 | |||
| 382 | Buf *buf_out_name = (cmd == CmdTest) ? buf_create_from_str("test") : | ||
| 383 | (out_name == nullptr) ? nullptr : buf_create_from_str(out_name); | ||
| 334 | if (buf_eql_str(&in_file_buf, "-")) { | 384 | if (buf_eql_str(&in_file_buf, "-")) { |
| 335 | os_get_cwd(&root_source_dir); | 385 | os_get_cwd(&root_source_dir); |
| 336 | if ((err = os_fetch_file(stdin, &root_source_code))) { | 386 | if ((err = os_fetch_file(stdin, &root_source_code))) { |
| ... | @@ -338,12 +388,24 @@ int main(int argc, char **argv) { | ... | @@ -338,12 +388,24 @@ int main(int argc, char **argv) { |
| 338 | return 1; | 388 | return 1; |
| 339 | } | 389 | } |
| 340 | buf_init_from_str(&root_source_name, ""); | 390 | buf_init_from_str(&root_source_name, ""); |
| 391 | |||
| 341 | } else { | 392 | } else { |
| 342 | os_path_split(&in_file_buf, &root_source_dir, &root_source_name); | 393 | os_path_split(&in_file_buf, &root_source_dir, &root_source_name); |
| 343 | if ((err = os_fetch_file_path(buf_create_from_str(in_file), &root_source_code))) { | 394 | if ((err = os_fetch_file_path(buf_create_from_str(in_file), &root_source_code))) { |
| 344 | fprintf(stderr, "unable to open '%s': %s\n", in_file, err_str(err)); | 395 | fprintf(stderr, "unable to open '%s': %s\n", in_file, err_str(err)); |
| 345 | return 1; | 396 | return 1; |
| 346 | } | 397 | } |
| 398 | |||
| 399 | if (cmd == CmdBuild && buf_out_name == nullptr) { | ||
| 400 | buf_out_name = buf_alloc(); | ||
| 401 | Buf ext_name = BUF_INIT; | ||
| 402 | os_path_extname(&root_source_name, buf_out_name, &ext_name); | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | if (cmd == CmdBuild && buf_out_name == nullptr) { | ||
| 407 | fprintf(stderr, "--name [name] not provided and unable to infer\n\n"); | ||
| 408 | return usage(arg0); | ||
| 347 | } | 409 | } |
| 348 | 410 | ||
| 349 | CodeGen *g = codegen_create(&root_source_dir, target); | 411 | CodeGen *g = codegen_create(&root_source_dir, target); |
| ... | @@ -361,11 +423,7 @@ int main(int argc, char **argv) { | ... | @@ -361,11 +423,7 @@ int main(int argc, char **argv) { |
| 361 | } else if (cmd == CmdTest) { | 423 | } else if (cmd == CmdTest) { |
| 362 | codegen_set_out_type(g, OutTypeExe); | 424 | codegen_set_out_type(g, OutTypeExe); |
| 363 | } | 425 | } |
| 364 | if (out_name) { | 426 | codegen_set_out_name(g, buf_out_name); |
| 365 | codegen_set_out_name(g, buf_create_from_str(out_name)); | ||
| 366 | } else if (cmd == CmdTest) { | ||
| 367 | codegen_set_out_name(g, buf_create_from_str("test")); | ||
| 368 | } | ||
| 369 | if (libc_lib_dir) | 427 | if (libc_lib_dir) |
| 370 | codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir)); | 428 | codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir)); |
| 371 | if (libc_static_lib_dir) | 429 | if (libc_static_lib_dir) |
src/os.cpp+26| ... | @@ -139,6 +139,32 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) { | ... | @@ -139,6 +139,32 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) { |
| 139 | if (out_basename) buf_init_from_buf(out_basename, full_path); | 139 | if (out_basename) buf_init_from_buf(out_basename, full_path); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | void os_path_extname(Buf *full_path, Buf *out_basename, Buf *out_extname) { | ||
| 143 | if (buf_len(full_path) == 0) { | ||
| 144 | buf_init_from_str(out_basename, ""); | ||
| 145 | buf_init_from_str(out_extname, ""); | ||
| 146 | return; | ||
| 147 | } | ||
| 148 | size_t i = buf_len(full_path) - 1; | ||
| 149 | while (true) { | ||
| 150 | if (buf_ptr(full_path)[i] == '.') { | ||
| 151 | buf_resize(out_basename, 0); | ||
| 152 | buf_append_mem(out_basename, buf_ptr(full_path), i); | ||
| 153 | |||
| 154 | buf_resize(out_extname, 0); | ||
| 155 | buf_append_mem(out_extname, buf_ptr(full_path) + i, buf_len(full_path) - i); | ||
| 156 | return; | ||
| 157 | } | ||
| 158 | |||
| 159 | if (i == 0) { | ||
| 160 | buf_init_from_buf(out_basename, full_path); | ||
| 161 | buf_init_from_str(out_extname, ""); | ||
| 162 | return; | ||
| 163 | } | ||
| 164 | i -= 1; | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 142 | void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) { | 168 | void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) { |
| 143 | buf_init_from_buf(out_full_path, dirname); | 169 | buf_init_from_buf(out_full_path, dirname); |
| 144 | uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1); | 170 | uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1); |
src/os.hpp+1| ... | @@ -34,6 +34,7 @@ int os_exec_process(const char *exe, ZigList<const char *> &args, | ... | @@ -34,6 +34,7 @@ int os_exec_process(const char *exe, ZigList<const char *> &args, |
| 34 | 34 | ||
| 35 | void os_path_dirname(Buf *full_path, Buf *out_dirname); | 35 | void os_path_dirname(Buf *full_path, Buf *out_dirname); |
| 36 | void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename); | 36 | void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename); |
| 37 | void os_path_extname(Buf *full_path, Buf *out_basename, Buf *out_extname); | ||
| 37 | void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path); | 38 | void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path); |
| 38 | int os_path_real(Buf *rel_path, Buf *out_abs_path); | 39 | int os_path_real(Buf *rel_path, Buf *out_abs_path); |
| 39 | void os_path_resolve(Buf *ref_path, Buf *target_path, Buf *out_abs_path); | 40 | void os_path_resolve(Buf *ref_path, Buf *target_path, Buf *out_abs_path); |
std/build.zig created+59| ... | @@ -0,0 +1,59 @@ | ||
| 1 | const io = @import("io.zig"); | ||
| 2 | const mem = @import("mem.zig"); | ||
| 3 | const debug = @import("debug.zig"); | ||
| 4 | const List = @import("list.zig").List; | ||
| 5 | const Allocator = @import("mem.zig").Allocator; | ||
| 6 | |||
| 7 | error ExtraArg; | ||
| 8 | |||
| 9 | pub const Builder = struct { | ||
| 10 | zig_exe: []const u8, | ||
| 11 | allocator: &Allocator, | ||
| 12 | exe_list: List(&Exe), | ||
| 13 | |||
| 14 | pub fn init(zig_exe: []const u8, allocator: &Allocator) -> Builder { | ||
| 15 | Builder { | ||
| 16 | .zig_exe = zig_exe, | ||
| 17 | .allocator = allocator, | ||
| 18 | .exe_list = List(&Exe).init(allocator), | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | pub fn addExe(self: &Builder, root_src: []const u8, name: []const u8) -> &Exe { | ||
| 23 | return self.addExeErr(root_src, name) %% |err| handleErr(err); | ||
| 24 | } | ||
| 25 | |||
| 26 | pub fn addExeErr(self: &Builder, root_src: []const u8, name: []const u8) -> %&Exe { | ||
| 27 | const exe = %return self.allocator.create(Exe); | ||
| 28 | *exe = Exe { | ||
| 29 | .root_src = root_src, | ||
| 30 | .name = name, | ||
| 31 | }; | ||
| 32 | %return self.exe_list.append(exe); | ||
| 33 | return exe; | ||
| 34 | } | ||
| 35 | |||
| 36 | pub fn make(self: &Builder, args: []const []const u8) -> %void { | ||
| 37 | var verbose = false; | ||
| 38 | for (args) |arg| { | ||
| 39 | if (mem.eql(u8, arg, "--verbose")) { | ||
| 40 | verbose = true; | ||
| 41 | } else { | ||
| 42 | %%io.stderr.printf("Unrecognized argument: '{}'\n", arg); | ||
| 43 | return error.ExtraArg; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | for (self.exe_list.toSlice()) |exe| { | ||
| 47 | %%io.stderr.printf("TODO: invoke this command:\nzig build_exe {} --name {}\n", exe.root_src, exe.name); | ||
| 48 | } | ||
| 49 | } | ||
| 50 | }; | ||
| 51 | |||
| 52 | const Exe = struct { | ||
| 53 | root_src: []const u8, | ||
| 54 | name: []const u8, | ||
| 55 | }; | ||
| 56 | |||
| 57 | fn handleErr(err: error) -> noreturn { | ||
| 58 | debug.panic("error: {}\n", @errorName(err)); | ||
| 59 | } | ||
std/debug.zig+3-4| ... | @@ -15,7 +15,7 @@ pub fn assert(ok: bool) { | ... | @@ -15,7 +15,7 @@ pub fn assert(ok: bool) { |
| 15 | 15 | ||
| 16 | var panicking = false; | 16 | var panicking = false; |
| 17 | /// This is the default panic implementation. | 17 | /// This is the default panic implementation. |
| 18 | pub coldcc fn panic(message: []const u8) -> noreturn { | 18 | pub coldcc fn panic(comptime format: []const u8, args: ...) -> noreturn { |
| 19 | // TODO | 19 | // TODO |
| 20 | // if (@atomicRmw(AtomicOp.XChg, &panicking, true, AtomicOrder.SeqCst)) { } | 20 | // if (@atomicRmw(AtomicOp.XChg, &panicking, true, AtomicOrder.SeqCst)) { } |
| 21 | if (panicking) { | 21 | if (panicking) { |
| ... | @@ -28,7 +28,7 @@ pub coldcc fn panic(message: []const u8) -> noreturn { | ... | @@ -28,7 +28,7 @@ pub coldcc fn panic(message: []const u8) -> noreturn { |
| 28 | panicking = true; | 28 | panicking = true; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | %%io.stderr.printf("{}\n", message); | 31 | %%io.stderr.printf(format, args); |
| 32 | %%printStackTrace(); | 32 | %%printStackTrace(); |
| 33 | 33 | ||
| 34 | os.abort(); | 34 | os.abort(); |
| ... | @@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void { | ... | @@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void { |
| 74 | const name = %return compile_unit.die.getAttrString(st, DW.AT_name); | 74 | const name = %return compile_unit.die.getAttrString(st, DW.AT_name); |
| 75 | 75 | ||
| 76 | %return out_stream.printf("{} -> {}\n", return_address, name); | 76 | %return out_stream.printf("{} -> {}\n", return_address, name); |
| 77 | maybe_fp = *(&const ?&const u8)(fp); | 77 | maybe_fp = *@bitcast(&const ?&const u8, fp); |
| 78 | } | 78 | } |
| 79 | }, | 79 | }, |
| 80 | ObjectFormat.coff => { | 80 | ObjectFormat.coff => { |
| ... | @@ -511,7 +511,6 @@ pub var global_allocator = mem.Allocator { | ... | @@ -511,7 +511,6 @@ pub var global_allocator = mem.Allocator { |
| 511 | .allocFn = globalAlloc, | 511 | .allocFn = globalAlloc, |
| 512 | .reallocFn = globalRealloc, | 512 | .reallocFn = globalRealloc, |
| 513 | .freeFn = globalFree, | 513 | .freeFn = globalFree, |
| 514 | .context = null, | ||
| 515 | }; | 514 | }; |
| 516 | 515 | ||
| 517 | var some_mem: [100 * 1024]u8 = undefined; | 516 | var some_mem: [100 * 1024]u8 = undefined; |
std/hash_map.zig+1-1| ... | @@ -236,7 +236,7 @@ test "basicHashMapTest" { | ... | @@ -236,7 +236,7 @@ test "basicHashMapTest" { |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | fn hash_i32(x: i32) -> u32 { | 238 | fn hash_i32(x: i32) -> u32 { |
| 239 | *(&u32)(&x) | 239 | *@bitcast(&u32, &x) |
| 240 | } | 240 | } |
| 241 | fn eql_i32(a: i32, b: i32) -> bool { | 241 | fn eql_i32(a: i32, b: i32) -> bool { |
| 242 | a == b | 242 | a == b |
std/index.zig+1| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | pub const build = @import("build.zig"); | ||
| 1 | pub const c = @import("c/index.zig"); | 2 | pub const c = @import("c/index.zig"); |
| 2 | pub const cstr = @import("cstr.zig"); | 3 | pub const cstr = @import("cstr.zig"); |
| 3 | pub const debug = @import("debug.zig"); | 4 | pub const debug = @import("debug.zig"); |
std/mem.zig+64-2| ... | @@ -7,12 +7,10 @@ pub const Cmp = math.Cmp; | ... | @@ -7,12 +7,10 @@ pub const Cmp = math.Cmp; |
| 7 | 7 | ||
| 8 | error NoMem; | 8 | error NoMem; |
| 9 | 9 | ||
| 10 | pub type Context = u8; | ||
| 11 | pub const Allocator = struct { | 10 | pub const Allocator = struct { |
| 12 | allocFn: fn (self: &Allocator, n: usize) -> %[]u8, | 11 | allocFn: fn (self: &Allocator, n: usize) -> %[]u8, |
| 13 | reallocFn: fn (self: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8, | 12 | reallocFn: fn (self: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8, |
| 14 | freeFn: fn (self: &Allocator, mem: []u8), | 13 | freeFn: fn (self: &Allocator, mem: []u8), |
| 15 | context: ?&Context, | ||
| 16 | 14 | ||
| 17 | /// Aborts the program if an allocation fails. | 15 | /// Aborts the program if an allocation fails. |
| 18 | fn checkedAlloc(self: &Allocator, comptime T: type, n: usize) -> []T { | 16 | fn checkedAlloc(self: &Allocator, comptime T: type, n: usize) -> []T { |
| ... | @@ -22,6 +20,14 @@ pub const Allocator = struct { | ... | @@ -22,6 +20,14 @@ pub const Allocator = struct { |
| 22 | } | 20 | } |
| 23 | } | 21 | } |
| 24 | 22 | ||
| 23 | fn create(self: &Allocator, comptime T: type) -> %&T { | ||
| 24 | &(%return self.alloc(T, 1))[0] | ||
| 25 | } | ||
| 26 | |||
| 27 | fn destroy(self: &Allocator, ptr: var) { | ||
| 28 | self.free(ptr[0...1]); | ||
| 29 | } | ||
| 30 | |||
| 25 | fn alloc(self: &Allocator, comptime T: type, n: usize) -> %[]T { | 31 | fn alloc(self: &Allocator, comptime T: type, n: usize) -> %[]T { |
| 26 | const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n); | 32 | const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n); |
| 27 | ([]T)(%return self.allocFn(self, byte_count)) | 33 | ([]T)(%return self.allocFn(self, byte_count)) |
| ... | @@ -37,6 +43,62 @@ pub const Allocator = struct { | ... | @@ -37,6 +43,62 @@ pub const Allocator = struct { |
| 37 | } | 43 | } |
| 38 | }; | 44 | }; |
| 39 | 45 | ||
| 46 | pub const IncrementingAllocator = struct { | ||
| 47 | allocator: Allocator, | ||
| 48 | bytes: []u8, | ||
| 49 | end_index: usize, | ||
| 50 | |||
| 51 | fn init(capacity: usize) -> %IncrementingAllocator { | ||
| 52 | switch (@compileVar("os")) { | ||
| 53 | Os.linux, Os.darwin, Os.macosx, Os.ios => { | ||
| 54 | const p = os.posix; | ||
| 55 | const addr = p.mmap(null, capacity, p.PROT_READ|p.PROT_WRITE, | ||
| 56 | p.MAP_PRIVATE|p.MAP_ANONYMOUS|p.MAP_NORESERVE, -1, 0); | ||
| 57 | if (addr == p.MAP_FAILED) { | ||
| 58 | return error.NoMem; | ||
| 59 | } | ||
| 60 | return IncrementingAllocator { | ||
| 61 | .allocator = Allocator { | ||
| 62 | .allocFn = alloc, | ||
| 63 | .reallocFn = realloc, | ||
| 64 | .freeFn = free, | ||
| 65 | }, | ||
| 66 | .bytes = (&u8)(addr)[0...capacity], | ||
| 67 | .end_index = 0, | ||
| 68 | }; | ||
| 69 | }, | ||
| 70 | else => @compileError("Unsupported OS"), | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | fn deinit(self: &IncrementingAllocator) { | ||
| 75 | _ = os.posix.munmap(self.bytes.ptr, self.bytes.len); | ||
| 76 | } | ||
| 77 | |||
| 78 | fn alloc(allocator: &Allocator, n: usize) -> %[]u8 { | ||
| 79 | // TODO | ||
| 80 | //const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator); | ||
| 81 | const self = @bitcast(&IncrementingAllocator, allocator); | ||
| 82 | const new_end_index = self.end_index + n; | ||
| 83 | if (new_end_index > self.bytes.len) { | ||
| 84 | return error.NoMem; | ||
| 85 | } | ||
| 86 | const result = self.bytes[self.end_index...new_end_index]; | ||
| 87 | self.end_index = new_end_index; | ||
| 88 | return result; | ||
| 89 | } | ||
| 90 | |||
| 91 | fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8 { | ||
| 92 | const result = %return alloc(allocator, new_size); | ||
| 93 | copy(u8, result, old_mem); | ||
| 94 | return result; | ||
| 95 | } | ||
| 96 | |||
| 97 | fn free(allocator: &Allocator, bytes: []u8) { | ||
| 98 | // Do nothing. That's the point of an incrementing allocator. | ||
| 99 | } | ||
| 100 | }; | ||
| 101 | |||
| 40 | /// Copy all of source into dest at position 0. | 102 | /// Copy all of source into dest at position 0. |
| 41 | /// dest.len must be >= source.len. | 103 | /// dest.len must be >= source.len. |
| 42 | pub fn copy(comptime T: type, dest: []T, source: []const T) { | 104 | pub fn copy(comptime T: type, dest: []T, source: []const T) { |
std/os/linux.zig+24-11| ... | @@ -5,16 +5,29 @@ const arch = switch (@compileVar("arch")) { | ... | @@ -5,16 +5,29 @@ const arch = switch (@compileVar("arch")) { |
| 5 | }; | 5 | }; |
| 6 | const errno = @import("errno.zig"); | 6 | const errno = @import("errno.zig"); |
| 7 | 7 | ||
| 8 | pub const MMAP_PROT_NONE = 0; | 8 | pub const PROT_NONE = 0; |
| 9 | pub const MMAP_PROT_READ = 1; | 9 | pub const PROT_READ = 1; |
| 10 | pub const MMAP_PROT_WRITE = 2; | 10 | pub const PROT_WRITE = 2; |
| 11 | pub const MMAP_PROT_EXEC = 4; | 11 | pub const PROT_EXEC = 4; |
| 12 | 12 | pub const PROT_GROWSDOWN = 0x01000000; | |
| 13 | pub const MMAP_MAP_FILE = 0; | 13 | pub const PROT_GROWSUP = 0x02000000; |
| 14 | pub const MMAP_MAP_SHARED = 1; | 14 | |
| 15 | pub const MMAP_MAP_PRIVATE = 2; | 15 | pub const MAP_FAILED = @maxValue(usize); |
| 16 | pub const MMAP_MAP_FIXED = 16; | 16 | pub const MAP_SHARED = 0x01; |
| 17 | pub const MMAP_MAP_ANON = 32; | 17 | pub const MAP_PRIVATE = 0x02; |
| 18 | pub const MAP_TYPE = 0x0f; | ||
| 19 | pub const MAP_FIXED = 0x10; | ||
| 20 | pub const MAP_ANONYMOUS = 0x20; | ||
| 21 | pub const MAP_NORESERVE = 0x4000; | ||
| 22 | pub const MAP_GROWSDOWN = 0x0100; | ||
| 23 | pub const MAP_DENYWRITE = 0x0800; | ||
| 24 | pub const MAP_EXECUTABLE = 0x1000; | ||
| 25 | pub const MAP_LOCKED = 0x2000; | ||
| 26 | pub const MAP_POPULATE = 0x8000; | ||
| 27 | pub const MAP_NONBLOCK = 0x10000; | ||
| 28 | pub const MAP_STACK = 0x20000; | ||
| 29 | pub const MAP_HUGETLB = 0x40000; | ||
| 30 | pub const MAP_FILE = 0; | ||
| 18 | 31 | ||
| 19 | pub const SIGHUP = 1; | 32 | pub const SIGHUP = 1; |
| 20 | pub const SIGINT = 2; | 33 | pub const SIGINT = 2; |
| ... | @@ -226,7 +239,7 @@ pub const AF_MAX = PF_MAX; | ... | @@ -226,7 +239,7 @@ pub const AF_MAX = PF_MAX; |
| 226 | 239 | ||
| 227 | /// Get the errno from a syscall return value, or 0 for no error. | 240 | /// Get the errno from a syscall return value, or 0 for no error. |
| 228 | pub fn getErrno(r: usize) -> usize { | 241 | pub fn getErrno(r: usize) -> usize { |
| 229 | const signed_r = *(&isize)(&r); | 242 | const signed_r = *@bitcast(&isize, &r); |
| 230 | if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0 | 243 | if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0 |
| 231 | } | 244 | } |
| 232 | 245 |
std/special/build_runner.zig created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | const root = @import("@build"); | ||
| 2 | const std = @import("std"); | ||
| 3 | const io = std.io; | ||
| 4 | const Builder = std.build.Builder; | ||
| 5 | const mem = std.mem; | ||
| 6 | |||
| 7 | pub fn main(args: [][]u8) -> %void { | ||
| 8 | const zig_exe = args[1]; | ||
| 9 | const leftover_args = args[2...]; | ||
| 10 | |||
| 11 | // TODO use a more general purpose allocator here | ||
| 12 | var inc_allocator = %%mem.IncrementingAllocator.init(10 * 1024 * 1024); | ||
| 13 | defer inc_allocator.deinit(); | ||
| 14 | |||
| 15 | var builder = Builder.init(zig_exe, &inc_allocator.allocator); | ||
| 16 | root.build(&builder); | ||
| 17 | %return builder.make(leftover_args); | ||
| 18 | } | ||
std/special/compiler_rt.zig+12-12| ... | @@ -15,7 +15,7 @@ export fn __udivdi3(a: du_int, b: du_int) -> du_int { | ... | @@ -15,7 +15,7 @@ export fn __udivdi3(a: du_int, b: du_int) -> du_int { |
| 15 | 15 | ||
| 16 | fn du_int_to_udwords(x: du_int) -> udwords { | 16 | fn du_int_to_udwords(x: du_int) -> udwords { |
| 17 | @setDebugSafety(this, false); | 17 | @setDebugSafety(this, false); |
| 18 | return *(&udwords)(&x); | 18 | return *@bitcast(&udwords, &x); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | 21 | export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| ... | @@ -66,7 +66,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -66,7 +66,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 66 | if (var rem ?= maybe_rem) { | 66 | if (var rem ?= maybe_rem) { |
| 67 | r[high] = n[high] % d[high]; | 67 | r[high] = n[high] % d[high]; |
| 68 | r[low] = 0; | 68 | r[low] = 0; |
| 69 | *rem = *(&du_int)(&r[0]); | 69 | *rem = *@bitcast(&du_int, &r[0]); |
| 70 | } | 70 | } |
| 71 | return n[high] / d[high]; | 71 | return n[high] / d[high]; |
| 72 | } | 72 | } |
| ... | @@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 78 | if (var rem ?= maybe_rem) { | 78 | if (var rem ?= maybe_rem) { |
| 79 | r[low] = n[low]; | 79 | r[low] = n[low]; |
| 80 | r[high] = n[high] & (d[high] - 1); | 80 | r[high] = n[high] & (d[high] - 1); |
| 81 | *rem = *(&du_int)(&r[0]); | 81 | *rem = *@bitcast(&du_int, &r[0]); |
| 82 | } | 82 | } |
| 83 | return n[high] >> @ctz(d[high]); | 83 | return n[high] >> @ctz(d[high]); |
| 84 | } | 84 | } |
| ... | @@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 89 | // 0 <= sr <= n_uword_bits - 2 or sr large | 89 | // 0 <= sr <= n_uword_bits - 2 or sr large |
| 90 | if (sr > n_uword_bits - 2) { | 90 | if (sr > n_uword_bits - 2) { |
| 91 | if (var rem ?= maybe_rem) { | 91 | if (var rem ?= maybe_rem) { |
| 92 | *rem = *(&du_int)(&n[0]); | 92 | *rem = *@bitcast(&du_int, &n[0]); |
| 93 | } | 93 | } |
| 94 | return 0; | 94 | return 0; |
| 95 | } | 95 | } |
| ... | @@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 113 | *rem = n[low] & (d[low] - 1); | 113 | *rem = n[low] & (d[low] - 1); |
| 114 | } | 114 | } |
| 115 | if (d[low] == 1) { | 115 | if (d[low] == 1) { |
| 116 | return *(&du_int)(&n[0]); | 116 | return *@bitcast(&du_int, &n[0]); |
| 117 | } | 117 | } |
| 118 | sr = @ctz(d[low]); | 118 | sr = @ctz(d[low]); |
| 119 | q[high] = n[high] >> sr; | 119 | q[high] = n[high] >> sr; |
| 120 | q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr); | 120 | q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr); |
| 121 | return *(&du_int)(&q[0]); | 121 | return *@bitcast(&du_int, &q[0]); |
| 122 | } | 122 | } |
| 123 | // K X | 123 | // K X |
| 124 | // --- | 124 | // --- |
| ... | @@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 154 | // 0 <= sr <= n_uword_bits - 1 or sr large | 154 | // 0 <= sr <= n_uword_bits - 1 or sr large |
| 155 | if (sr > n_uword_bits - 1) { | 155 | if (sr > n_uword_bits - 1) { |
| 156 | if (var rem ?= maybe_rem) { | 156 | if (var rem ?= maybe_rem) { |
| 157 | *rem = *(&du_int)(&n[0]); | 157 | *rem = *@bitcast(&du_int, &n[0]); |
| 158 | } | 158 | } |
| 159 | return 0; | 159 | return 0; |
| 160 | } | 160 | } |
| ... | @@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | ... | @@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 191 | // r.all -= d.all; | 191 | // r.all -= d.all; |
| 192 | // carry = 1; | 192 | // carry = 1; |
| 193 | // } | 193 | // } |
| 194 | const s: di_int = (di_int)(*(&du_int)(&d[0]) - *(&du_int)(&r[0]) - 1) >> (n_udword_bits - 1); | 194 | const s: di_int = (di_int)(*@bitcast(&du_int, &d[0]) - *@bitcast(&du_int, &r[0]) - 1) >> (n_udword_bits - 1); |
| 195 | carry = su_int(s & 1); | 195 | carry = su_int(s & 1); |
| 196 | *(&du_int)(&r[0]) -= *(&du_int)(&d[0]) & u64(s); | 196 | *@bitcast(&du_int, &r[0]) -= *@bitcast(&du_int, &d[0]) & u64(s); |
| 197 | 197 | ||
| 198 | sr -= 1; | 198 | sr -= 1; |
| 199 | } | 199 | } |
| 200 | *(&du_int)(&q[0]) = (*(&du_int)(&q[0]) << 1) | u64(carry); | 200 | *@bitcast(&du_int, &q[0]) = (*@bitcast(&du_int, &q[0]) << 1) | u64(carry); |
| 201 | if (var rem ?= maybe_rem) { | 201 | if (var rem ?= maybe_rem) { |
| 202 | *rem = *(&du_int)(&r[0]); | 202 | *rem = *@bitcast(&du_int, &r[0]); |
| 203 | } | 203 | } |
| 204 | return *(&du_int)(&q[0]); | 204 | return *@bitcast(&du_int, &q[0]); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | export fn __umoddi3(a: du_int, b: du_int) -> du_int { | 207 | export fn __umoddi3(a: du_int, b: du_int) -> du_int { |
std/special/zigrt.zig+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | // This file contains functions that zig depends on to coordinate between | 1 | // This file contains functions that zig depends on to coordinate between |
| 2 | // multiple .o files. The symbols are defined LinkOnce so that multiple | 2 | // multiple .o files. The symbols are defined Weak so that multiple |
| 3 | // instances of zig_rt.zig do not conflict with each other. | 3 | // instances of zig_rt.zig do not conflict with each other. |
| 4 | 4 | ||
| 5 | export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> noreturn { | 5 | export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> noreturn { |
| ... | @@ -11,6 +11,6 @@ export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> nore | ... | @@ -11,6 +11,6 @@ export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> nore |
| 11 | } else if (@compileVar("os") == Os.freestanding) { | 11 | } else if (@compileVar("os") == Os.freestanding) { |
| 12 | while (true) {} | 12 | while (true) {} |
| 13 | } else { | 13 | } else { |
| 14 | @import("std").debug.panic(message_ptr[0...message_len]); | 14 | @import("std").debug.panic("{}\n", message_ptr[0...message_len]); |
| 15 | } | 15 | } |
| 16 | } | 16 | } |
test/cases/cast.zig+12-1| ... | @@ -15,7 +15,18 @@ test "numLitIntToPtrCast" { | ... | @@ -15,7 +15,18 @@ test "numLitIntToPtrCast" { |
| 15 | test "pointerReinterpretConstFloatToInt" { | 15 | test "pointerReinterpretConstFloatToInt" { |
| 16 | const float: f64 = 5.99999999999994648725e-01; | 16 | const float: f64 = 5.99999999999994648725e-01; |
| 17 | const float_ptr = &float; | 17 | const float_ptr = &float; |
| 18 | const int_ptr = (&i32)(float_ptr); | 18 | const int_ptr = @bitcast(&i32, float_ptr); |
| 19 | const int_val = *int_ptr; | 19 | const int_val = *int_ptr; |
| 20 | assert(int_val == 858993411); | 20 | assert(int_val == 858993411); |
| 21 | } | 21 | } |
| 22 | |||
| 23 | test "implicitly cast a pointer to a const pointer of it" { | ||
| 24 | var x: i32 = 1; | ||
| 25 | const xp = &x; | ||
| 26 | funcWithConstPtrPtr(xp); | ||
| 27 | assert(x == 2); | ||
| 28 | } | ||
| 29 | |||
| 30 | fn funcWithConstPtrPtr(x: &const &i32) { | ||
| 31 | **x += 1; | ||
| 32 | } |
test/cases/eval.zig+15| ... | @@ -284,3 +284,18 @@ fn testCompTimeUIntComparisons(x: u32) { | ... | @@ -284,3 +284,18 @@ fn testCompTimeUIntComparisons(x: u32) { |
| 284 | @compileError("this condition should be comptime known"); | 284 | @compileError("this condition should be comptime known"); |
| 285 | } | 285 | } |
| 286 | } | 286 | } |
| 287 | |||
| 288 | |||
| 289 | |||
| 290 | test "const ptr to variable data changes at runtime" { | ||
| 291 | assert(foo_ref.name[0] == 'a'); | ||
| 292 | foo_ref.name = "b"; | ||
| 293 | assert(foo_ref.name[0] == 'b'); | ||
| 294 | } | ||
| 295 | |||
| 296 | const Foo = struct { | ||
| 297 | name: []const u8, | ||
| 298 | }; | ||
| 299 | |||
| 300 | var foo_contents = Foo { .name = "a", }; | ||
| 301 | const foo_ref = &foo_contents; |
test/cases/generics.zig+1-1| ... | @@ -121,5 +121,5 @@ test "genericFnWithImplicitCast" { | ... | @@ -121,5 +121,5 @@ test "genericFnWithImplicitCast" { |
| 121 | } | 121 | } |
| 122 | fn getByte(ptr: ?&const u8) -> u8 {*??ptr} | 122 | fn getByte(ptr: ?&const u8) -> u8 {*??ptr} |
| 123 | fn getFirstByte(comptime T: type, mem: []const T) -> u8 { | 123 | fn getFirstByte(comptime T: type, mem: []const T) -> u8 { |
| 124 | getByte((&const u8)(&mem[0])) | 124 | getByte(@bitcast(&const u8, &mem[0])) |
| 125 | } | 125 | } |
test/cases/misc.zig+4-4| ... | @@ -246,15 +246,15 @@ test "typeEquality" { | ... | @@ -246,15 +246,15 @@ test "typeEquality" { |
| 246 | 246 | ||
| 247 | const global_a: i32 = 1234; | 247 | const global_a: i32 = 1234; |
| 248 | const global_b: &const i32 = &global_a; | 248 | const global_b: &const i32 = &global_a; |
| 249 | const global_c: &const f32 = (&const f32)(global_b); | 249 | const global_c: &const f32 = @bitcast(&const f32, global_b); |
| 250 | test "compileTimeGlobalReinterpret" { | 250 | test "compileTimeGlobalReinterpret" { |
| 251 | const d = (&const i32)(global_c); | 251 | const d = @bitcast(&const i32, global_c); |
| 252 | assert(*d == 1234); | 252 | assert(*d == 1234); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | test "explicitCastMaybePointers" { | 255 | test "explicitCastMaybePointers" { |
| 256 | const a: ?&i32 = undefined; | 256 | const a: ?&i32 = undefined; |
| 257 | const b: ?&f32 = (?&f32)(a); | 257 | const b: ?&f32 = @bitcast(?&f32, a); |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | test "genericMallocFree" { | 260 | test "genericMallocFree" { |
| ... | @@ -263,7 +263,7 @@ test "genericMallocFree" { | ... | @@ -263,7 +263,7 @@ test "genericMallocFree" { |
| 263 | } | 263 | } |
| 264 | const some_mem : [100]u8 = undefined; | 264 | const some_mem : [100]u8 = undefined; |
| 265 | fn memAlloc(comptime T: type, n: usize) -> %[]T { | 265 | fn memAlloc(comptime T: type, n: usize) -> %[]T { |
| 266 | return (&T)(&some_mem[0])[0...n]; | 266 | return @bitcast(&T, &some_mem[0])[0...n]; |
| 267 | } | 267 | } |
| 268 | fn memFree(comptime T: type, memory: []T) { } | 268 | fn memFree(comptime T: type, memory: []T) { } |
| 269 | 269 |
test/cases/struct.zig+1-1| ... | @@ -41,7 +41,7 @@ const VoidStructFieldsFoo = struct { | ... | @@ -41,7 +41,7 @@ const VoidStructFieldsFoo = struct { |
| 41 | 41 | ||
| 42 | test "fn" { | 42 | test "fn" { |
| 43 | var foo: StructFoo = undefined; | 43 | var foo: StructFoo = undefined; |
| 44 | @memset((&u8)(&foo), 0, @sizeOf(StructFoo)); | 44 | @memset(@bitcast(&u8, &foo), 0, @sizeOf(StructFoo)); |
| 45 | foo.a += 1; | 45 | foo.a += 1; |
| 46 | foo.b = foo.a == 1; | 46 | foo.b = foo.a == 1; |
| 47 | testFoo(foo); | 47 | testFoo(foo); |
test/run_tests.cpp+7-18| ... | @@ -73,10 +73,8 @@ static TestCase *add_simple_case(const char *case_name, const char *source, cons | ... | @@ -73,10 +73,8 @@ static TestCase *add_simple_case(const char *case_name, const char *source, cons |
| 73 | test_case->source_files.at(0).relative_path = tmp_source_path; | 73 | test_case->source_files.at(0).relative_path = tmp_source_path; |
| 74 | test_case->source_files.at(0).source_code = source; | 74 | test_case->source_files.at(0).source_code = source; |
| 75 | 75 | ||
| 76 | test_case->compiler_args.append("build"); | 76 | test_case->compiler_args.append("build_exe"); |
| 77 | test_case->compiler_args.append(tmp_source_path); | 77 | test_case->compiler_args.append(tmp_source_path); |
| 78 | test_case->compiler_args.append("--export"); | ||
| 79 | test_case->compiler_args.append("exe"); | ||
| 80 | test_case->compiler_args.append("--name"); | 78 | test_case->compiler_args.append("--name"); |
| 81 | test_case->compiler_args.append("test"); | 79 | test_case->compiler_args.append("test"); |
| 82 | test_case->compiler_args.append("--output"); | 80 | test_case->compiler_args.append("--output"); |
| ... | @@ -113,15 +111,12 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source | ... | @@ -113,15 +111,12 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source |
| 113 | test_case->compile_errors.append(arg); | 111 | test_case->compile_errors.append(arg); |
| 114 | } | 112 | } |
| 115 | 113 | ||
| 116 | test_case->compiler_args.append("build"); | 114 | test_case->compiler_args.append("build_obj"); |
| 117 | test_case->compiler_args.append(tmp_source_path); | 115 | test_case->compiler_args.append(tmp_source_path); |
| 118 | 116 | ||
| 119 | test_case->compiler_args.append("--name"); | 117 | test_case->compiler_args.append("--name"); |
| 120 | test_case->compiler_args.append("test"); | 118 | test_case->compiler_args.append("test"); |
| 121 | 119 | ||
| 122 | test_case->compiler_args.append("--export"); | ||
| 123 | test_case->compiler_args.append("obj"); | ||
| 124 | |||
| 125 | test_case->compiler_args.append("--output"); | 120 | test_case->compiler_args.append("--output"); |
| 126 | test_case->compiler_args.append(tmp_exe_path); | 121 | test_case->compiler_args.append(tmp_exe_path); |
| 127 | 122 | ||
| ... | @@ -142,15 +137,12 @@ static void add_debug_safety_case(const char *case_name, const char *source) { | ... | @@ -142,15 +137,12 @@ static void add_debug_safety_case(const char *case_name, const char *source) { |
| 142 | test_case->source_files.at(0).relative_path = tmp_source_path; | 137 | test_case->source_files.at(0).relative_path = tmp_source_path; |
| 143 | test_case->source_files.at(0).source_code = source; | 138 | test_case->source_files.at(0).source_code = source; |
| 144 | 139 | ||
| 145 | test_case->compiler_args.append("build"); | 140 | test_case->compiler_args.append("build_exe"); |
| 146 | test_case->compiler_args.append(tmp_source_path); | 141 | test_case->compiler_args.append(tmp_source_path); |
| 147 | 142 | ||
| 148 | test_case->compiler_args.append("--name"); | 143 | test_case->compiler_args.append("--name"); |
| 149 | test_case->compiler_args.append("test"); | 144 | test_case->compiler_args.append("test"); |
| 150 | 145 | ||
| 151 | test_case->compiler_args.append("--export"); | ||
| 152 | test_case->compiler_args.append("exe"); | ||
| 153 | |||
| 154 | test_case->compiler_args.append("--output"); | 146 | test_case->compiler_args.append("--output"); |
| 155 | test_case->compiler_args.append(tmp_exe_path); | 147 | test_case->compiler_args.append(tmp_exe_path); |
| 156 | 148 | ||
| ... | @@ -164,15 +156,12 @@ static void add_debug_safety_case(const char *case_name, const char *source) { | ... | @@ -164,15 +156,12 @@ static void add_debug_safety_case(const char *case_name, const char *source) { |
| 164 | test_case->source_files.at(0).source_code = source; | 156 | test_case->source_files.at(0).source_code = source; |
| 165 | test_case->output = ""; | 157 | test_case->output = ""; |
| 166 | 158 | ||
| 167 | test_case->compiler_args.append("build"); | 159 | test_case->compiler_args.append("build_exe"); |
| 168 | test_case->compiler_args.append(tmp_source_path); | 160 | test_case->compiler_args.append(tmp_source_path); |
| 169 | 161 | ||
| 170 | test_case->compiler_args.append("--name"); | 162 | test_case->compiler_args.append("--name"); |
| 171 | test_case->compiler_args.append("test"); | 163 | test_case->compiler_args.append("test"); |
| 172 | 164 | ||
| 173 | test_case->compiler_args.append("--export"); | ||
| 174 | test_case->compiler_args.append("exe"); | ||
| 175 | |||
| 176 | test_case->compiler_args.append("--output"); | 165 | test_case->compiler_args.append("--output"); |
| 177 | test_case->compiler_args.append(tmp_exe_path); | 166 | test_case->compiler_args.append(tmp_exe_path); |
| 178 | 167 | ||
| ... | @@ -471,8 +460,8 @@ const foo : i32 = 0; | ... | @@ -471,8 +460,8 @@ const foo : i32 = 0; |
| 471 | const c = @cImport(@cInclude("stdlib.h")); | 460 | const c = @cImport(@cInclude("stdlib.h")); |
| 472 | 461 | ||
| 473 | export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { | 462 | export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { |
| 474 | const a_int = (&i32)(a ?? unreachable); | 463 | const a_int = @bitcast(&i32, a ?? unreachable); |
| 475 | const b_int = (&i32)(b ?? unreachable); | 464 | const b_int = @bitcast(&i32, b ?? unreachable); |
| 476 | if (*a_int < *b_int) { | 465 | if (*a_int < *b_int) { |
| 477 | -1 | 466 | -1 |
| 478 | } else if (*a_int > *b_int) { | 467 | } else if (*a_int > *b_int) { |
| ... | @@ -485,7 +474,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { | ... | @@ -485,7 +474,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { |
| 485 | export fn main(args: c_int, argv: &&u8) -> c_int { | 474 | export fn main(args: c_int, argv: &&u8) -> c_int { |
| 486 | var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 }; | 475 | var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 }; |
| 487 | 476 | ||
| 488 | c.qsort((&c_void)(&array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn); | 477 | c.qsort(@bitcast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn); |
| 489 | 478 | ||
| 490 | for (array) |item, i| { | 479 | for (array) |item, i| { |
| 491 | if (item != i) { | 480 | if (item != i) { |