remove coroutines implementation and promise type
This commit is contained in:
parent
f429f4dcab
commit
54e716afdc
@ -466,7 +466,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
|
||||
comp.link_objects = link_objects;
|
||||
|
||||
comp.start();
|
||||
const process_build_events_handle = try async<loop.allocator> processBuildEvents(comp, color);
|
||||
// TODO const process_build_events_handle = try async<loop.allocator> processBuildEvents(comp, color);
|
||||
defer cancel process_build_events_handle;
|
||||
loop.run();
|
||||
}
|
||||
@ -578,7 +578,7 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
|
||||
var zig_compiler = try ZigCompiler.init(&loop);
|
||||
defer zig_compiler.deinit();
|
||||
|
||||
const handle = try async<loop.allocator> findLibCAsync(&zig_compiler);
|
||||
// TODO const handle = try async<loop.allocator> findLibCAsync(&zig_compiler);
|
||||
defer cancel handle;
|
||||
|
||||
loop.run();
|
||||
@ -663,12 +663,12 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
|
||||
defer loop.deinit();
|
||||
|
||||
var result: FmtError!void = undefined;
|
||||
const main_handle = try async<allocator> asyncFmtMainChecked(
|
||||
&result,
|
||||
&loop,
|
||||
&flags,
|
||||
color,
|
||||
);
|
||||
// TODO const main_handle = try async<allocator> asyncFmtMainChecked(
|
||||
// TODO &result,
|
||||
// TODO &loop,
|
||||
// TODO &flags,
|
||||
// TODO color,
|
||||
// TODO );
|
||||
defer cancel main_handle;
|
||||
loop.run();
|
||||
return result;
|
||||
|
@ -70,17 +70,6 @@ struct IrExecutable {
|
||||
Scope *begin_scope;
|
||||
ZigList<Tld *> tld_list;
|
||||
|
||||
IrInstruction *coro_handle;
|
||||
IrInstruction *atomic_state_field_ptr; // this one is shared and in the promise
|
||||
IrInstruction *coro_result_ptr_field_ptr;
|
||||
IrInstruction *coro_result_field_ptr;
|
||||
IrInstruction *await_handle_var_ptr; // this one is where we put the one we extracted from the promise
|
||||
IrBasicBlock *coro_early_final;
|
||||
IrBasicBlock *coro_normal_final;
|
||||
IrBasicBlock *coro_suspend_block;
|
||||
IrBasicBlock *coro_final_cleanup_block;
|
||||
ZigVar *coro_allocator_var;
|
||||
|
||||
bool invalid;
|
||||
bool is_inline;
|
||||
bool is_generic_instantiation;
|
||||
@ -489,7 +478,6 @@ enum NodeType {
|
||||
NodeTypeResume,
|
||||
NodeTypeAwaitExpr,
|
||||
NodeTypeSuspend,
|
||||
NodeTypePromiseType,
|
||||
NodeTypeEnumLiteral,
|
||||
};
|
||||
|
||||
@ -522,7 +510,6 @@ struct AstNodeFnProto {
|
||||
AstNode *section_expr;
|
||||
|
||||
bool auto_err_set;
|
||||
AstNode *async_allocator_type;
|
||||
};
|
||||
|
||||
struct AstNodeFnDef {
|
||||
@ -657,7 +644,6 @@ struct AstNodeFnCallExpr {
|
||||
bool is_builtin;
|
||||
bool is_async;
|
||||
bool seen; // used by @compileLog
|
||||
AstNode *async_allocator;
|
||||
};
|
||||
|
||||
struct AstNodeArrayAccessExpr {
|
||||
@ -949,10 +935,6 @@ struct AstNodeSuspend {
|
||||
AstNode *block;
|
||||
};
|
||||
|
||||
struct AstNodePromiseType {
|
||||
AstNode *payload_type; // can be NULL
|
||||
};
|
||||
|
||||
struct AstNodeEnumLiteral {
|
||||
Token *period;
|
||||
Token *identifier;
|
||||
@ -1018,7 +1000,6 @@ struct AstNode {
|
||||
AstNodeResumeExpr resume_expr;
|
||||
AstNodeAwaitExpr await_expr;
|
||||
AstNodeSuspend suspend;
|
||||
AstNodePromiseType promise_type;
|
||||
AstNodeEnumLiteral enum_literal;
|
||||
} data;
|
||||
};
|
||||
@ -1047,7 +1028,6 @@ struct FnTypeId {
|
||||
bool is_var_args;
|
||||
CallingConvention cc;
|
||||
uint32_t alignment;
|
||||
ZigType *async_allocator_type;
|
||||
};
|
||||
|
||||
uint32_t fn_type_id_hash(FnTypeId*);
|
||||
@ -1241,11 +1221,6 @@ struct ZigTypeBoundFn {
|
||||
ZigType *fn_type;
|
||||
};
|
||||
|
||||
struct ZigTypePromise {
|
||||
// null if `promise` instead of `promise->T`
|
||||
ZigType *result_type;
|
||||
};
|
||||
|
||||
struct ZigTypeVector {
|
||||
// The type must be a pointer, integer, or float
|
||||
ZigType *elem_type;
|
||||
@ -1276,7 +1251,6 @@ enum ZigTypeId {
|
||||
ZigTypeIdBoundFn,
|
||||
ZigTypeIdArgTuple,
|
||||
ZigTypeIdOpaque,
|
||||
ZigTypeIdPromise,
|
||||
ZigTypeIdVector,
|
||||
ZigTypeIdEnumLiteral,
|
||||
};
|
||||
@ -1314,7 +1288,6 @@ struct ZigType {
|
||||
ZigTypeUnion unionation;
|
||||
ZigTypeFn fn;
|
||||
ZigTypeBoundFn bound_fn;
|
||||
ZigTypePromise promise;
|
||||
ZigTypeVector vector;
|
||||
ZigTypeOpaque opaque;
|
||||
} data;
|
||||
@ -1322,8 +1295,6 @@ struct ZigType {
|
||||
// use these fields to make sure we don't duplicate type table entries for the same type
|
||||
ZigType *pointer_parent[2]; // [0 - mut, 1 - const]
|
||||
ZigType *optional_parent;
|
||||
ZigType *promise_parent;
|
||||
ZigType *promise_frame_parent;
|
||||
// If we generate a constant name value for this type, we memoize it here.
|
||||
// The type of this is array
|
||||
ConstExprValue *cached_const_name_val;
|
||||
@ -1709,20 +1680,6 @@ struct CodeGen {
|
||||
LLVMValueRef trap_fn_val;
|
||||
LLVMValueRef return_address_fn_val;
|
||||
LLVMValueRef frame_address_fn_val;
|
||||
LLVMValueRef coro_destroy_fn_val;
|
||||
LLVMValueRef coro_id_fn_val;
|
||||
LLVMValueRef coro_alloc_fn_val;
|
||||
LLVMValueRef coro_size_fn_val;
|
||||
LLVMValueRef coro_begin_fn_val;
|
||||
LLVMValueRef coro_suspend_fn_val;
|
||||
LLVMValueRef coro_end_fn_val;
|
||||
LLVMValueRef coro_free_fn_val;
|
||||
LLVMValueRef coro_resume_fn_val;
|
||||
LLVMValueRef coro_save_fn_val;
|
||||
LLVMValueRef coro_promise_fn_val;
|
||||
LLVMValueRef coro_alloc_helper_fn_val;
|
||||
LLVMValueRef coro_frame_fn_val;
|
||||
LLVMValueRef merge_err_ret_traces_fn_val;
|
||||
LLVMValueRef add_error_return_trace_addr_fn_val;
|
||||
LLVMValueRef stacksave_fn_val;
|
||||
LLVMValueRef stackrestore_fn_val;
|
||||
@ -1797,7 +1754,6 @@ struct CodeGen {
|
||||
ZigType *entry_var;
|
||||
ZigType *entry_global_error_set;
|
||||
ZigType *entry_arg_tuple;
|
||||
ZigType *entry_promise;
|
||||
ZigType *entry_enum_literal;
|
||||
} builtin_types;
|
||||
ZigType *align_amt_type;
|
||||
@ -1985,7 +1941,6 @@ enum ScopeId {
|
||||
ScopeIdSuspend,
|
||||
ScopeIdFnDef,
|
||||
ScopeIdCompTime,
|
||||
ScopeIdCoroPrelude,
|
||||
ScopeIdRuntime,
|
||||
};
|
||||
|
||||
@ -2128,12 +2083,6 @@ struct ScopeFnDef {
|
||||
ZigFn *fn_entry;
|
||||
};
|
||||
|
||||
// This scope is created to indicate that the code in the scope
|
||||
// is auto-generated coroutine prelude stuff.
|
||||
struct ScopeCoroPrelude {
|
||||
Scope base;
|
||||
};
|
||||
|
||||
// synchronized with code in define_builtin_compile_vars
|
||||
enum AtomicOrder {
|
||||
AtomicOrderUnordered,
|
||||
@ -2231,7 +2180,6 @@ enum IrInstructionId {
|
||||
IrInstructionIdSetRuntimeSafety,
|
||||
IrInstructionIdSetFloatMode,
|
||||
IrInstructionIdArrayType,
|
||||
IrInstructionIdPromiseType,
|
||||
IrInstructionIdSliceType,
|
||||
IrInstructionIdGlobalAsm,
|
||||
IrInstructionIdAsm,
|
||||
@ -2329,26 +2277,10 @@ enum IrInstructionId {
|
||||
IrInstructionIdErrorReturnTrace,
|
||||
IrInstructionIdErrorUnion,
|
||||
IrInstructionIdCancel,
|
||||
IrInstructionIdGetImplicitAllocator,
|
||||
IrInstructionIdCoroId,
|
||||
IrInstructionIdCoroAlloc,
|
||||
IrInstructionIdCoroSize,
|
||||
IrInstructionIdCoroBegin,
|
||||
IrInstructionIdCoroAllocFail,
|
||||
IrInstructionIdCoroSuspend,
|
||||
IrInstructionIdCoroEnd,
|
||||
IrInstructionIdCoroFree,
|
||||
IrInstructionIdCoroResume,
|
||||
IrInstructionIdCoroSave,
|
||||
IrInstructionIdCoroPromise,
|
||||
IrInstructionIdCoroAllocHelper,
|
||||
IrInstructionIdAtomicRmw,
|
||||
IrInstructionIdAtomicLoad,
|
||||
IrInstructionIdPromiseResultType,
|
||||
IrInstructionIdAwaitBookkeeping,
|
||||
IrInstructionIdSaveErrRetAddr,
|
||||
IrInstructionIdAddImplicitReturnType,
|
||||
IrInstructionIdMergeErrRetTraces,
|
||||
IrInstructionIdMarkErrRetTracePtr,
|
||||
IrInstructionIdErrSetCast,
|
||||
IrInstructionIdToBytes,
|
||||
@ -2606,7 +2538,6 @@ struct IrInstructionCallSrc {
|
||||
IrInstruction **args;
|
||||
ResultLoc *result_loc;
|
||||
|
||||
IrInstruction *async_allocator;
|
||||
IrInstruction *new_stack;
|
||||
FnInline fn_inline;
|
||||
bool is_async;
|
||||
@ -2622,7 +2553,6 @@ struct IrInstructionCallGen {
|
||||
IrInstruction **args;
|
||||
IrInstruction *result_loc;
|
||||
|
||||
IrInstruction *async_allocator;
|
||||
IrInstruction *new_stack;
|
||||
FnInline fn_inline;
|
||||
bool is_async;
|
||||
@ -2743,12 +2673,6 @@ struct IrInstructionPtrType {
|
||||
bool is_allow_zero;
|
||||
};
|
||||
|
||||
struct IrInstructionPromiseType {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *payload_type;
|
||||
};
|
||||
|
||||
struct IrInstructionSliceType {
|
||||
IrInstruction base;
|
||||
|
||||
@ -3178,7 +3102,6 @@ struct IrInstructionFnProto {
|
||||
IrInstruction **param_types;
|
||||
IrInstruction *align_value;
|
||||
IrInstruction *return_type;
|
||||
IrInstruction *async_allocator_type_value;
|
||||
bool is_var_args;
|
||||
};
|
||||
|
||||
@ -3414,89 +3337,6 @@ struct IrInstructionCancel {
|
||||
IrInstruction *target;
|
||||
};
|
||||
|
||||
enum ImplicitAllocatorId {
|
||||
ImplicitAllocatorIdArg,
|
||||
ImplicitAllocatorIdLocalVar,
|
||||
};
|
||||
|
||||
struct IrInstructionGetImplicitAllocator {
|
||||
IrInstruction base;
|
||||
|
||||
ImplicitAllocatorId id;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroId {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *promise_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroAlloc {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *coro_id;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroSize {
|
||||
IrInstruction base;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroBegin {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *coro_id;
|
||||
IrInstruction *coro_mem_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroAllocFail {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *err_val;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroSuspend {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *save_point;
|
||||
IrInstruction *is_final;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroEnd {
|
||||
IrInstruction base;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroFree {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *coro_id;
|
||||
IrInstruction *coro_handle;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroResume {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *awaiter_handle;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroSave {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *coro_handle;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroPromise {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *coro_handle;
|
||||
};
|
||||
|
||||
struct IrInstructionCoroAllocHelper {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *realloc_fn;
|
||||
IrInstruction *coro_size;
|
||||
};
|
||||
|
||||
struct IrInstructionAtomicRmw {
|
||||
IrInstruction base;
|
||||
|
||||
@ -3518,18 +3358,6 @@ struct IrInstructionAtomicLoad {
|
||||
AtomicOrder resolved_ordering;
|
||||
};
|
||||
|
||||
struct IrInstructionPromiseResultType {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *promise_type;
|
||||
};
|
||||
|
||||
struct IrInstructionAwaitBookkeeping {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *promise_result_type;
|
||||
};
|
||||
|
||||
struct IrInstructionSaveErrRetAddr {
|
||||
IrInstruction base;
|
||||
};
|
||||
@ -3540,14 +3368,6 @@ struct IrInstructionAddImplicitReturnType {
|
||||
IrInstruction *value;
|
||||
};
|
||||
|
||||
struct IrInstructionMergeErrRetTraces {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *coro_promise_ptr;
|
||||
IrInstruction *src_err_ret_trace_ptr;
|
||||
IrInstruction *dest_err_ret_trace_ptr;
|
||||
};
|
||||
|
||||
struct IrInstructionMarkErrRetTracePtr {
|
||||
IrInstruction base;
|
||||
|
||||
@ -3777,17 +3597,6 @@ static const size_t err_union_payload_index = 1;
|
||||
// MUST BE A POWER OF TWO.
|
||||
static const size_t stack_trace_ptr_count = 32;
|
||||
|
||||
// these belong to the async function
|
||||
#define RETURN_ADDRESSES_FIELD_NAME "return_addresses"
|
||||
#define ERR_RET_TRACE_FIELD_NAME "err_ret_trace"
|
||||
#define RESULT_FIELD_NAME "result"
|
||||
#define ASYNC_REALLOC_FIELD_NAME "reallocFn"
|
||||
#define ASYNC_SHRINK_FIELD_NAME "shrinkFn"
|
||||
#define ATOMIC_STATE_FIELD_NAME "atomic_state"
|
||||
// these point to data belonging to the awaiter
|
||||
#define ERR_RET_TRACE_PTR_FIELD_NAME "err_ret_trace_ptr"
|
||||
#define RESULT_PTR_FIELD_NAME "result_ptr"
|
||||
|
||||
#define NAMESPACE_SEP_CHAR '.'
|
||||
#define NAMESPACE_SEP_STR "."
|
||||
|
||||
|
172
src/analyze.cpp
172
src/analyze.cpp
@ -188,12 +188,6 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
return &scope->base;
|
||||
}
|
||||
|
||||
Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent) {
|
||||
ScopeCoroPrelude *scope = allocate<ScopeCoroPrelude>(1);
|
||||
init_scope(g, &scope->base, ScopeIdCoroPrelude, node, parent);
|
||||
return &scope->base;
|
||||
}
|
||||
|
||||
ZigType *get_scope_import(Scope *scope) {
|
||||
while (scope) {
|
||||
if (scope->id == ScopeIdDecls) {
|
||||
@ -254,7 +248,6 @@ AstNode *type_decl_node(ZigType *type_entry) {
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
return nullptr;
|
||||
}
|
||||
@ -307,7 +300,6 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
return true;
|
||||
}
|
||||
@ -341,31 +333,6 @@ ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
|
||||
return get_int_type(g, false, bits_needed_for_unsigned(x));
|
||||
}
|
||||
|
||||
ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {
|
||||
if (result_type != nullptr && result_type->promise_parent != nullptr) {
|
||||
return result_type->promise_parent;
|
||||
} else if (result_type == nullptr && g->builtin_types.entry_promise != nullptr) {
|
||||
return g->builtin_types.entry_promise;
|
||||
}
|
||||
|
||||
ZigType *entry = new_type_table_entry(ZigTypeIdPromise);
|
||||
entry->abi_size = g->builtin_types.entry_usize->abi_size;
|
||||
entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
|
||||
entry->abi_align = g->builtin_types.entry_usize->abi_align;
|
||||
entry->data.promise.result_type = result_type;
|
||||
buf_init_from_str(&entry->name, "promise");
|
||||
if (result_type != nullptr) {
|
||||
buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name));
|
||||
}
|
||||
|
||||
if (result_type != nullptr) {
|
||||
result_type->promise_parent = entry;
|
||||
} else if (result_type == nullptr) {
|
||||
g->builtin_types.entry_promise = entry;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
static const char *ptr_len_to_star_str(PtrLen ptr_len) {
|
||||
switch (ptr_len) {
|
||||
case PtrLenSingle:
|
||||
@ -490,42 +457,6 @@ ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {
|
||||
return get_pointer_to_type_extra(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false);
|
||||
}
|
||||
|
||||
ZigType *get_promise_frame_type(CodeGen *g, ZigType *return_type) {
|
||||
if (return_type->promise_frame_parent != nullptr) {
|
||||
return return_type->promise_frame_parent;
|
||||
}
|
||||
|
||||
ZigType *atomic_state_type = g->builtin_types.entry_usize;
|
||||
ZigType *result_ptr_type = get_pointer_to_type(g, return_type, false);
|
||||
|
||||
ZigList<const char *> field_names = {};
|
||||
field_names.append(ATOMIC_STATE_FIELD_NAME);
|
||||
field_names.append(RESULT_FIELD_NAME);
|
||||
field_names.append(RESULT_PTR_FIELD_NAME);
|
||||
if (g->have_err_ret_tracing) {
|
||||
field_names.append(ERR_RET_TRACE_PTR_FIELD_NAME);
|
||||
field_names.append(ERR_RET_TRACE_FIELD_NAME);
|
||||
field_names.append(RETURN_ADDRESSES_FIELD_NAME);
|
||||
}
|
||||
|
||||
ZigList<ZigType *> field_types = {};
|
||||
field_types.append(atomic_state_type);
|
||||
field_types.append(return_type);
|
||||
field_types.append(result_ptr_type);
|
||||
if (g->have_err_ret_tracing) {
|
||||
field_types.append(get_ptr_to_stack_trace_type(g));
|
||||
field_types.append(g->stack_trace_type);
|
||||
field_types.append(get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count));
|
||||
}
|
||||
|
||||
assert(field_names.length == field_types.length);
|
||||
Buf *name = buf_sprintf("AsyncFramePromise(%s)", buf_ptr(&return_type->name));
|
||||
ZigType *entry = get_struct_type(g, buf_ptr(name), field_names.items, field_types.items, field_names.length);
|
||||
|
||||
return_type->promise_frame_parent = entry;
|
||||
return entry;
|
||||
}
|
||||
|
||||
ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
|
||||
if (child_type->optional_parent != nullptr) {
|
||||
return child_type->optional_parent;
|
||||
@ -879,13 +810,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
|
||||
|
||||
// populate the name of the type
|
||||
buf_resize(&fn_type->name, 0);
|
||||
if (fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) {
|
||||
assert(fn_type_id->async_allocator_type != nullptr);
|
||||
buf_appendf(&fn_type->name, "async<%s> ", buf_ptr(&fn_type_id->async_allocator_type->name));
|
||||
} else {
|
||||
const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
|
||||
buf_appendf(&fn_type->name, "%s", cc_str);
|
||||
}
|
||||
const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
|
||||
buf_appendf(&fn_type->name, "%s", cc_str);
|
||||
buf_appendf(&fn_type->name, "fn(");
|
||||
for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
|
||||
FnTypeParamInfo *param_info = &fn_type_id->param_info[i];
|
||||
@ -998,14 +924,8 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
|
||||
ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
|
||||
ZigType *fn_type = new_type_table_entry(ZigTypeIdFn);
|
||||
buf_resize(&fn_type->name, 0);
|
||||
if (fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) {
|
||||
const char *async_allocator_type_str = (fn_type->data.fn.fn_type_id.async_allocator_type == nullptr) ?
|
||||
"var" : buf_ptr(&fn_type_id->async_allocator_type->name);
|
||||
buf_appendf(&fn_type->name, "async(%s) ", async_allocator_type_str);
|
||||
} else {
|
||||
const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
|
||||
buf_appendf(&fn_type->name, "%s", cc_str);
|
||||
}
|
||||
const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
|
||||
buf_appendf(&fn_type->name, "%s", cc_str);
|
||||
buf_appendf(&fn_type->name, "fn(");
|
||||
size_t i = 0;
|
||||
for (; i < fn_type_id->next_param_index; i += 1) {
|
||||
@ -1119,7 +1039,6 @@ static Error emit_error_unless_type_allowed_in_packed_struct(CodeGen *g, ZigType
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdPromise:
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("type '%s' not allowed in packed struct; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name)));
|
||||
@ -1207,7 +1126,6 @@ bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVoid:
|
||||
return false;
|
||||
case ZigTypeIdOpaque:
|
||||
@ -1378,7 +1296,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
switch (type_requires_comptime(g, type_entry)) {
|
||||
case ReqCompTimeNo:
|
||||
@ -1474,7 +1391,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
switch (type_requires_comptime(g, fn_type_id.return_type)) {
|
||||
case ReqCompTimeInvalid:
|
||||
@ -1487,16 +1403,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
||||
break;
|
||||
}
|
||||
|
||||
if (fn_type_id.cc == CallingConventionAsync) {
|
||||
if (fn_proto->async_allocator_type == nullptr) {
|
||||
return get_generic_fn_type(g, &fn_type_id);
|
||||
}
|
||||
fn_type_id.async_allocator_type = analyze_type_expr(g, child_scope, fn_proto->async_allocator_type);
|
||||
if (type_is_invalid(fn_type_id.async_allocator_type)) {
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
return get_fn_type(g, &fn_type_id);
|
||||
}
|
||||
|
||||
@ -3039,7 +2945,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||
case NodeTypeResume:
|
||||
case NodeTypeAwaitExpr:
|
||||
case NodeTypeSuspend:
|
||||
case NodeTypePromiseType:
|
||||
case NodeTypeEnumLiteral:
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -3091,7 +2996,6 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
return type_entry;
|
||||
}
|
||||
@ -3591,7 +3495,6 @@ bool is_container(ZigType *type_entry) {
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
return false;
|
||||
}
|
||||
@ -3648,7 +3551,6 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
|
||||
case ZigTypeIdInvalid:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -3658,13 +3560,11 @@ Error resolve_container_type(CodeGen *g, ZigType *type_entry) {
|
||||
ZigType *get_src_ptr_type(ZigType *type) {
|
||||
if (type->id == ZigTypeIdPointer) return type;
|
||||
if (type->id == ZigTypeIdFn) return type;
|
||||
if (type->id == ZigTypeIdPromise) return type;
|
||||
if (type->id == ZigTypeIdOptional) {
|
||||
if (type->data.maybe.child_type->id == ZigTypeIdPointer) {
|
||||
return type->data.maybe.child_type->data.pointer.allow_zero ? nullptr : type->data.maybe.child_type;
|
||||
}
|
||||
if (type->data.maybe.child_type->id == ZigTypeIdFn) return type->data.maybe.child_type;
|
||||
if (type->data.maybe.child_type->id == ZigTypeIdPromise) return type->data.maybe.child_type;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -3691,8 +3591,6 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
|
||||
// when getting the alignment of `?extern fn() void`.
|
||||
// See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html
|
||||
return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment;
|
||||
} else if (ptr_type->id == ZigTypeIdPromise) {
|
||||
return get_coro_frame_align_bytes(g);
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -3704,8 +3602,6 @@ bool get_ptr_const(ZigType *type) {
|
||||
return ptr_type->data.pointer.is_const;
|
||||
} else if (ptr_type->id == ZigTypeIdFn) {
|
||||
return true;
|
||||
} else if (ptr_type->id == ZigTypeIdPromise) {
|
||||
return true;
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -4102,7 +3998,6 @@ bool handle_is_ptr(ZigType *type_entry) {
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
return false;
|
||||
case ZigTypeIdArray:
|
||||
@ -4142,7 +4037,6 @@ uint32_t fn_type_id_hash(FnTypeId *id) {
|
||||
result += ((uint32_t)(id->cc)) * (uint32_t)3349388391;
|
||||
result += id->is_var_args ? (uint32_t)1931444534 : 0;
|
||||
result += hash_ptr(id->return_type);
|
||||
result += hash_ptr(id->async_allocator_type);
|
||||
result += id->alignment * 0xd3b3f3e2;
|
||||
for (size_t i = 0; i < id->param_count; i += 1) {
|
||||
FnTypeParamInfo *info = &id->param_info[i];
|
||||
@ -4157,8 +4051,7 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) {
|
||||
a->return_type != b->return_type ||
|
||||
a->is_var_args != b->is_var_args ||
|
||||
a->param_count != b->param_count ||
|
||||
a->alignment != b->alignment ||
|
||||
a->async_allocator_type != b->async_allocator_type)
|
||||
a->alignment != b->alignment)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -4320,9 +4213,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
|
||||
return 3677364617 ^ hash_ptr(const_val->data.x_ptr.data.fn.fn_entry);
|
||||
case ZigTypeIdPointer:
|
||||
return hash_const_val_ptr(const_val);
|
||||
case ZigTypeIdPromise:
|
||||
// TODO better hashing algorithm
|
||||
return 223048345;
|
||||
case ZigTypeIdUndefined:
|
||||
return 162837799;
|
||||
case ZigTypeIdNull:
|
||||
@ -4418,7 +4308,6 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdEnum:
|
||||
return false;
|
||||
@ -4488,7 +4377,6 @@ static bool return_type_is_cacheable(ZigType *return_type) {
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdPointer:
|
||||
@ -4623,7 +4511,6 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBool:
|
||||
case ZigTypeIdFloat:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdErrorUnion:
|
||||
return OnePossibleValueNo;
|
||||
case ZigTypeIdUndefined:
|
||||
@ -4712,7 +4599,6 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
|
||||
case ZigTypeIdFloat:
|
||||
case ZigTypeIdVoid:
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdPromise:
|
||||
return ReqCompTimeNo;
|
||||
}
|
||||
zig_unreachable();
|
||||
@ -5278,7 +5164,6 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdInvalid:
|
||||
case ZigTypeIdUnreachable:
|
||||
case ZigTypeIdPromise:
|
||||
zig_unreachable();
|
||||
}
|
||||
zig_unreachable();
|
||||
@ -5611,8 +5496,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
|
||||
buf_appendf(buf, "(args value)");
|
||||
return;
|
||||
}
|
||||
case ZigTypeIdPromise:
|
||||
zig_unreachable();
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -5659,7 +5542,6 @@ uint32_t type_id_hash(TypeId x) {
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdPromise:
|
||||
zig_unreachable();
|
||||
case ZigTypeIdErrorUnion:
|
||||
return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
|
||||
@ -5701,7 +5583,6 @@ bool type_id_eql(TypeId a, TypeId b) {
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdOptional:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdUnion:
|
||||
@ -5874,7 +5755,6 @@ static const ZigTypeId all_type_ids[] = {
|
||||
ZigTypeIdBoundFn,
|
||||
ZigTypeIdArgTuple,
|
||||
ZigTypeIdOpaque,
|
||||
ZigTypeIdPromise,
|
||||
ZigTypeIdVector,
|
||||
ZigTypeIdEnumLiteral,
|
||||
};
|
||||
@ -5938,12 +5818,10 @@ size_t type_id_index(ZigType *entry) {
|
||||
return 20;
|
||||
case ZigTypeIdOpaque:
|
||||
return 21;
|
||||
case ZigTypeIdPromise:
|
||||
return 22;
|
||||
case ZigTypeIdVector:
|
||||
return 23;
|
||||
return 22;
|
||||
case ZigTypeIdEnumLiteral:
|
||||
return 24;
|
||||
return 23;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -5998,8 +5876,6 @@ const char *type_id_name(ZigTypeId id) {
|
||||
return "ArgTuple";
|
||||
case ZigTypeIdOpaque:
|
||||
return "Opaque";
|
||||
case ZigTypeIdPromise:
|
||||
return "Promise";
|
||||
case ZigTypeIdVector:
|
||||
return "Vector";
|
||||
}
|
||||
@ -6066,13 +5942,6 @@ bool type_is_global_error_set(ZigType *err_set_type) {
|
||||
return err_set_type->data.error_set.err_count == UINT32_MAX;
|
||||
}
|
||||
|
||||
uint32_t get_coro_frame_align_bytes(CodeGen *g) {
|
||||
uint32_t a = g->pointer_size_bytes * 2;
|
||||
// promises have at least alignment 8 so that we can have 3 extra bits when doing atomicrmw
|
||||
if (a < 8) a = 8;
|
||||
return a;
|
||||
}
|
||||
|
||||
bool type_can_fail(ZigType *type_entry) {
|
||||
return type_entry->id == ZigTypeIdErrorUnion || type_entry->id == ZigTypeIdErrorSet;
|
||||
}
|
||||
@ -7105,19 +6974,13 @@ static void resolve_llvm_types_fn(CodeGen *g, ZigType *fn_type) {
|
||||
param_di_types.append(get_llvm_di_type(g, gen_type));
|
||||
}
|
||||
if (is_async) {
|
||||
{
|
||||
// async allocator param
|
||||
ZigType *gen_type = fn_type_id->async_allocator_type;
|
||||
gen_param_types.append(get_llvm_type(g, gen_type));
|
||||
param_di_types.append(get_llvm_di_type(g, gen_type));
|
||||
}
|
||||
|
||||
{
|
||||
// error code pointer
|
||||
ZigType *gen_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
|
||||
gen_param_types.append(get_llvm_type(g, gen_type));
|
||||
param_di_types.append(get_llvm_di_type(g, gen_type));
|
||||
}
|
||||
// coroutine frame pointer
|
||||
// TODO if we can make this typed a little more it will be better for
|
||||
// debug symbols.
|
||||
// TODO do we need to make this aligned more?
|
||||
ZigType *void_star = get_pointer_to_type(g, g->builtin_types.entry_c_void, false);
|
||||
gen_param_types.append(get_llvm_type(g, void_star));
|
||||
param_di_types.append(get_llvm_di_type(g, void_star));
|
||||
}
|
||||
|
||||
fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
|
||||
@ -7224,13 +7087,6 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
|
||||
return resolve_llvm_types_union(g, type, wanted_resolve_status);
|
||||
case ZigTypeIdPointer:
|
||||
return resolve_llvm_types_pointer(g, type);
|
||||
case ZigTypeIdPromise: {
|
||||
if (type->llvm_di_type != nullptr) return;
|
||||
ZigType *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
|
||||
type->llvm_type = get_llvm_type(g, u8_ptr_type);
|
||||
type->llvm_di_type = get_llvm_di_type(g, u8_ptr_type);
|
||||
return;
|
||||
}
|
||||
case ZigTypeIdInt:
|
||||
return resolve_llvm_types_integer(g, type);
|
||||
case ZigTypeIdOptional:
|
||||
|
@ -39,8 +39,6 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
|
||||
ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);
|
||||
ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
|
||||
ZigType *field_types[], size_t field_count);
|
||||
ZigType *get_promise_type(CodeGen *g, ZigType *result_type);
|
||||
ZigType *get_promise_frame_type(CodeGen *g, ZigType *return_type);
|
||||
ZigType *get_test_fn_type(CodeGen *g);
|
||||
bool handle_is_ptr(ZigType *type_entry);
|
||||
|
||||
@ -117,7 +115,6 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
|
||||
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent);
|
||||
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime);
|
||||
|
||||
void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);
|
||||
@ -204,7 +201,6 @@ bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *sour
|
||||
|
||||
ZigType *get_auto_err_set_type(CodeGen *g, ZigFn *fn_entry);
|
||||
|
||||
uint32_t get_coro_frame_align_bytes(CodeGen *g);
|
||||
bool fn_type_can_fail(FnTypeId *fn_type_id);
|
||||
bool type_can_fail(ZigType *type_entry);
|
||||
bool fn_eval_cacheable(Scope *scope, ZigType *return_type);
|
||||
|
@ -257,8 +257,6 @@ static const char *node_type_str(NodeType node_type) {
|
||||
return "AwaitExpr";
|
||||
case NodeTypeSuspend:
|
||||
return "Suspend";
|
||||
case NodeTypePromiseType:
|
||||
return "PromiseType";
|
||||
case NodeTypePointerType:
|
||||
return "PointerType";
|
||||
case NodeTypeEnumLiteral:
|
||||
@ -692,13 +690,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||
fprintf(ar->f, "@");
|
||||
}
|
||||
if (node->data.fn_call_expr.is_async) {
|
||||
fprintf(ar->f, "async");
|
||||
if (node->data.fn_call_expr.async_allocator != nullptr) {
|
||||
fprintf(ar->f, "<");
|
||||
render_node_extra(ar, node->data.fn_call_expr.async_allocator, true);
|
||||
fprintf(ar->f, ">");
|
||||
}
|
||||
fprintf(ar->f, " ");
|
||||
fprintf(ar->f, "async ");
|
||||
}
|
||||
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
|
||||
bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr && fn_ref_node->type != NodeTypePointerType);
|
||||
@ -855,15 +847,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||
render_node_ungrouped(ar, node->data.inferred_array_type.child_type);
|
||||
break;
|
||||
}
|
||||
case NodeTypePromiseType:
|
||||
{
|
||||
fprintf(ar->f, "promise");
|
||||
if (node->data.promise_type.payload_type != nullptr) {
|
||||
fprintf(ar->f, "->");
|
||||
render_node_grouped(ar, node->data.promise_type.payload_type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NodeTypeErrorType:
|
||||
fprintf(ar->f, "anyerror");
|
||||
break;
|
||||
|
674
src/codegen.cpp
674
src/codegen.cpp
@ -721,7 +721,6 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
|
||||
case ScopeIdLoop:
|
||||
case ScopeIdSuspend:
|
||||
case ScopeIdCompTime:
|
||||
case ScopeIdCoroPrelude:
|
||||
case ScopeIdRuntime:
|
||||
return get_di_scope(g, scope->parent);
|
||||
}
|
||||
@ -1083,177 +1082,6 @@ static LLVMValueRef get_write_register_fn_val(CodeGen *g) {
|
||||
return g->write_register_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_destroy_fn_val(CodeGen *g) {
|
||||
if (g->coro_destroy_fn_val)
|
||||
return g->coro_destroy_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 1, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.destroy");
|
||||
g->coro_destroy_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_destroy_fn_val));
|
||||
|
||||
return g->coro_destroy_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_id_fn_val(CodeGen *g) {
|
||||
if (g->coro_id_fn_val)
|
||||
return g->coro_id_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
LLVMInt32Type(),
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()), param_types, 4, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.id");
|
||||
g->coro_id_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_id_fn_val));
|
||||
|
||||
return g->coro_id_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_alloc_fn_val(CodeGen *g) {
|
||||
if (g->coro_alloc_fn_val)
|
||||
return g->coro_alloc_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMInt1Type(), param_types, 1, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.alloc");
|
||||
g->coro_alloc_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_alloc_fn_val));
|
||||
|
||||
return g->coro_alloc_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_size_fn_val(CodeGen *g) {
|
||||
if (g->coro_size_fn_val)
|
||||
return g->coro_size_fn_val;
|
||||
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(g->builtin_types.entry_usize->llvm_type, nullptr, 0, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.size.i%d", g->pointer_size_bytes * 8);
|
||||
g->coro_size_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_size_fn_val));
|
||||
|
||||
return g->coro_size_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_begin_fn_val(CodeGen *g) {
|
||||
if (g->coro_begin_fn_val)
|
||||
return g->coro_begin_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()),
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), param_types, 2, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.begin");
|
||||
g->coro_begin_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_begin_fn_val));
|
||||
|
||||
return g->coro_begin_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_suspend_fn_val(CodeGen *g) {
|
||||
if (g->coro_suspend_fn_val)
|
||||
return g->coro_suspend_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()),
|
||||
LLVMInt1Type(),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMInt8Type(), param_types, 2, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.suspend");
|
||||
g->coro_suspend_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_suspend_fn_val));
|
||||
|
||||
return g->coro_suspend_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_end_fn_val(CodeGen *g) {
|
||||
if (g->coro_end_fn_val)
|
||||
return g->coro_end_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
LLVMInt1Type(),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMInt1Type(), param_types, 2, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.end");
|
||||
g->coro_end_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_end_fn_val));
|
||||
|
||||
return g->coro_end_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_free_fn_val(CodeGen *g) {
|
||||
if (g->coro_free_fn_val)
|
||||
return g->coro_free_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()),
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), param_types, 2, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.free");
|
||||
g->coro_free_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_free_fn_val));
|
||||
|
||||
return g->coro_free_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_resume_fn_val(CodeGen *g) {
|
||||
if (g->coro_resume_fn_val)
|
||||
return g->coro_resume_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 1, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.resume");
|
||||
g->coro_resume_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_resume_fn_val));
|
||||
|
||||
return g->coro_resume_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_save_fn_val(CodeGen *g) {
|
||||
if (g->coro_save_fn_val)
|
||||
return g->coro_save_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()), param_types, 1, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.save");
|
||||
g->coro_save_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_save_fn_val));
|
||||
|
||||
return g->coro_save_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_promise_fn_val(CodeGen *g) {
|
||||
if (g->coro_promise_fn_val)
|
||||
return g->coro_promise_fn_val;
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
LLVMPointerType(LLVMInt8Type(), 0),
|
||||
LLVMInt32Type(),
|
||||
LLVMInt1Type(),
|
||||
};
|
||||
LLVMTypeRef fn_type = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), param_types, 3, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.promise");
|
||||
g->coro_promise_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_promise_fn_val));
|
||||
|
||||
return g->coro_promise_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_return_address_fn_val(CodeGen *g) {
|
||||
if (g->return_address_fn_val)
|
||||
return g->return_address_fn_val;
|
||||
@ -1346,140 +1174,6 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
|
||||
return fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
|
||||
if (g->merge_err_ret_traces_fn_val)
|
||||
return g->merge_err_ret_traces_fn_val;
|
||||
|
||||
assert(g->stack_trace_type != nullptr);
|
||||
|
||||
LLVMTypeRef param_types[] = {
|
||||
get_llvm_type(g, get_ptr_to_stack_trace_type(g)),
|
||||
get_llvm_type(g, get_ptr_to_stack_trace_type(g)),
|
||||
};
|
||||
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), param_types, 2, false);
|
||||
|
||||
Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_merge_error_return_traces"), false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
|
||||
LLVMSetLinkage(fn_val, LLVMInternalLinkage);
|
||||
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
|
||||
addLLVMFnAttr(fn_val, "nounwind");
|
||||
add_uwtable_attr(g, fn_val);
|
||||
// Error return trace memory is in the stack, which is impossible to be at address 0
|
||||
// on any architecture.
|
||||
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
|
||||
addLLVMArgAttr(fn_val, (unsigned)0, "noalias");
|
||||
addLLVMArgAttr(fn_val, (unsigned)0, "writeonly");
|
||||
// Error return trace memory is in the stack, which is impossible to be at address 0
|
||||
// on any architecture.
|
||||
addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");
|
||||
addLLVMArgAttr(fn_val, (unsigned)1, "noalias");
|
||||
addLLVMArgAttr(fn_val, (unsigned)1, "readonly");
|
||||
if (g->build_mode == BuildModeDebug) {
|
||||
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
|
||||
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr);
|
||||
}
|
||||
|
||||
// this is above the ZigLLVMClearCurrentDebugLocation
|
||||
LLVMValueRef add_error_return_trace_addr_fn_val = get_add_error_return_trace_addr_fn(g);
|
||||
|
||||
LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry");
|
||||
LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
|
||||
LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder);
|
||||
LLVMPositionBuilderAtEnd(g->builder, entry_block);
|
||||
ZigLLVMClearCurrentDebugLocation(g->builder);
|
||||
|
||||
// var frame_index: usize = undefined;
|
||||
// var frames_left: usize = undefined;
|
||||
// if (src_stack_trace.index < src_stack_trace.instruction_addresses.len) {
|
||||
// frame_index = 0;
|
||||
// frames_left = src_stack_trace.index;
|
||||
// if (frames_left == 0) return;
|
||||
// } else {
|
||||
// frame_index = (src_stack_trace.index + 1) % src_stack_trace.instruction_addresses.len;
|
||||
// frames_left = src_stack_trace.instruction_addresses.len;
|
||||
// }
|
||||
// while (true) {
|
||||
// __zig_add_err_ret_trace_addr(dest_stack_trace, src_stack_trace.instruction_addresses[frame_index]);
|
||||
// frames_left -= 1;
|
||||
// if (frames_left == 0) return;
|
||||
// frame_index = (frame_index + 1) % src_stack_trace.instruction_addresses.len;
|
||||
// }
|
||||
LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return");
|
||||
|
||||
LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index");
|
||||
LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left");
|
||||
|
||||
LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0);
|
||||
LLVMValueRef src_stack_trace_ptr = LLVMGetParam(fn_val, 1);
|
||||
|
||||
size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;
|
||||
size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;
|
||||
LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
|
||||
(unsigned)src_index_field_index, "");
|
||||
LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
|
||||
(unsigned)src_addresses_field_index, "");
|
||||
ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;
|
||||
size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
|
||||
LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, "");
|
||||
size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;
|
||||
LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, "");
|
||||
LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, "");
|
||||
LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, "");
|
||||
LLVMValueRef src_len_val = LLVMBuildLoad(g->builder, src_len_field_ptr, "");
|
||||
LLVMValueRef no_wrap_bit = LLVMBuildICmp(g->builder, LLVMIntULT, src_index_val, src_len_val, "");
|
||||
LLVMBasicBlockRef no_wrap_block = LLVMAppendBasicBlock(fn_val, "NoWrap");
|
||||
LLVMBasicBlockRef yes_wrap_block = LLVMAppendBasicBlock(fn_val, "YesWrap");
|
||||
LLVMBasicBlockRef loop_block = LLVMAppendBasicBlock(fn_val, "Loop");
|
||||
LLVMBuildCondBr(g->builder, no_wrap_bit, no_wrap_block, yes_wrap_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, no_wrap_block);
|
||||
LLVMValueRef usize_zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type);
|
||||
LLVMBuildStore(g->builder, usize_zero, frame_index_ptr);
|
||||
LLVMBuildStore(g->builder, src_index_val, frames_left_ptr);
|
||||
LLVMValueRef frames_left_eq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, src_index_val, usize_zero, "");
|
||||
LLVMBuildCondBr(g->builder, frames_left_eq_zero_bit, return_block, loop_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, yes_wrap_block);
|
||||
LLVMValueRef usize_one = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 1, false);
|
||||
LLVMValueRef plus_one = LLVMBuildNUWAdd(g->builder, src_index_val, usize_one, "");
|
||||
LLVMValueRef mod_len = LLVMBuildURem(g->builder, plus_one, src_len_val, "");
|
||||
LLVMBuildStore(g->builder, mod_len, frame_index_ptr);
|
||||
LLVMBuildStore(g->builder, src_len_val, frames_left_ptr);
|
||||
LLVMBuildBr(g->builder, loop_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, loop_block);
|
||||
LLVMValueRef ptr_index = LLVMBuildLoad(g->builder, frame_index_ptr, "");
|
||||
LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, "");
|
||||
LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, "");
|
||||
LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val};
|
||||
ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAlways, "");
|
||||
LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, "");
|
||||
LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, "");
|
||||
LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, "");
|
||||
LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(fn_val, "Continue");
|
||||
LLVMBuildCondBr(g->builder, done_bit, return_block, continue_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, return_block);
|
||||
LLVMBuildRetVoid(g->builder);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, continue_block);
|
||||
LLVMBuildStore(g->builder, new_frames_left, frames_left_ptr);
|
||||
LLVMValueRef prev_index = LLVMBuildLoad(g->builder, frame_index_ptr, "");
|
||||
LLVMValueRef index_plus_one = LLVMBuildNUWAdd(g->builder, prev_index, usize_one, "");
|
||||
LLVMValueRef index_mod_len = LLVMBuildURem(g->builder, index_plus_one, src_len_val, "");
|
||||
LLVMBuildStore(g->builder, index_mod_len, frame_index_ptr);
|
||||
LLVMBuildBr(g->builder, loop_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, prev_block);
|
||||
if (!g->strip_debug_symbols) {
|
||||
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
|
||||
}
|
||||
|
||||
g->merge_err_ret_traces_fn_val = fn_val;
|
||||
return fn_val;
|
||||
|
||||
}
|
||||
|
||||
static LLVMValueRef get_return_err_fn(CodeGen *g) {
|
||||
if (g->return_err_fn != nullptr)
|
||||
return g->return_err_fn;
|
||||
@ -1667,24 +1361,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
|
||||
return fn_val;
|
||||
}
|
||||
|
||||
static bool is_coro_prelude_scope(Scope *scope) {
|
||||
while (scope != nullptr) {
|
||||
if (scope->id == ScopeIdCoroPrelude) {
|
||||
return true;
|
||||
} else if (scope->id == ScopeIdFnDef) {
|
||||
break;
|
||||
}
|
||||
scope = scope->parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static LLVMValueRef get_cur_err_ret_trace_val(CodeGen *g, Scope *scope) {
|
||||
if (!g->have_err_ret_tracing) {
|
||||
return nullptr;
|
||||
}
|
||||
if (g->cur_fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) {
|
||||
return is_coro_prelude_scope(scope) ? g->cur_err_ret_trace_val_arg : g->cur_err_ret_trace_val_stack;
|
||||
return g->cur_err_ret_trace_val_stack;
|
||||
}
|
||||
if (g->cur_err_ret_trace_val_stack != nullptr) {
|
||||
return g->cur_err_ret_trace_val_stack;
|
||||
@ -3697,19 +3379,6 @@ static bool get_prefix_arg_err_ret_stack(CodeGen *g, FnTypeId *fn_type_id) {
|
||||
fn_type_id->cc == CallingConventionAsync);
|
||||
}
|
||||
|
||||
static size_t get_async_allocator_arg_index(CodeGen *g, FnTypeId *fn_type_id) {
|
||||
// 0 1 2 3
|
||||
// err_ret_stack allocator_ptr err_code other_args...
|
||||
return get_prefix_arg_err_ret_stack(g, fn_type_id) ? 1 : 0;
|
||||
}
|
||||
|
||||
static size_t get_async_err_code_arg_index(CodeGen *g, FnTypeId *fn_type_id) {
|
||||
// 0 1 2 3
|
||||
// err_ret_stack allocator_ptr err_code other_args...
|
||||
return 1 + get_async_allocator_arg_index(g, fn_type_id);
|
||||
}
|
||||
|
||||
|
||||
static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) {
|
||||
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_ptr_index, "");
|
||||
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_len_index, "");
|
||||
@ -3778,10 +3447,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
|
||||
gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
|
||||
}
|
||||
if (instruction->is_async) {
|
||||
gen_param_values.append(ir_llvm_value(g, instruction->async_allocator));
|
||||
|
||||
LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
|
||||
gen_param_values.append(err_val_ptr);
|
||||
zig_panic("TODO codegen async call");
|
||||
}
|
||||
FnWalk fn_walk = {};
|
||||
fn_walk.id = FnWalkIdCall;
|
||||
@ -4471,10 +4137,6 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
|
||||
{
|
||||
align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment;
|
||||
ptr_val = target_val;
|
||||
} else if (target_type->id == ZigTypeIdOptional &&
|
||||
target_type->data.maybe.child_type->id == ZigTypeIdPromise)
|
||||
{
|
||||
zig_panic("TODO audit this function");
|
||||
} else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) {
|
||||
ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry;
|
||||
align_bytes = get_ptr_align(g, slice_ptr_type);
|
||||
@ -4519,17 +4181,7 @@ static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *execu
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_cancel(CodeGen *g, IrExecutable *executable, IrInstructionCancel *instruction) {
|
||||
LLVMValueRef target_handle = ir_llvm_value(g, instruction->target);
|
||||
LLVMBuildCall(g->builder, get_coro_destroy_fn_val(g), &target_handle, 1, "");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_get_implicit_allocator(CodeGen *g, IrExecutable *executable,
|
||||
IrInstructionGetImplicitAllocator *instruction)
|
||||
{
|
||||
assert(instruction->id == ImplicitAllocatorIdArg);
|
||||
size_t allocator_arg_index = get_async_allocator_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
|
||||
return LLVMGetParam(g->cur_fn_val, allocator_arg_index);
|
||||
zig_panic("TODO cancel");
|
||||
}
|
||||
|
||||
static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {
|
||||
@ -4840,24 +4492,10 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable
|
||||
return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef get_handle_fn_val(CodeGen *g) {
|
||||
if (g->coro_frame_fn_val)
|
||||
return g->coro_frame_fn_val;
|
||||
|
||||
LLVMTypeRef fn_type = LLVMFunctionType( LLVMPointerType(LLVMInt8Type(), 0)
|
||||
, nullptr, 0, false);
|
||||
Buf *name = buf_sprintf("llvm.coro.frame");
|
||||
g->coro_frame_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type);
|
||||
assert(LLVMGetIntrinsicID(g->coro_frame_fn_val));
|
||||
|
||||
return g->coro_frame_fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutable *executable,
|
||||
IrInstructionHandle *instruction)
|
||||
{
|
||||
LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, g->builtin_types.entry_promise));
|
||||
return LLVMBuildCall(g->builder, get_handle_fn_val(g), &zero, 0, "");
|
||||
zig_panic("TODO @handle() codegen");
|
||||
}
|
||||
|
||||
static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) {
|
||||
@ -5123,248 +4761,6 @@ static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInst
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_id(CodeGen *g, IrExecutable *executable, IrInstructionCoroId *instruction) {
|
||||
LLVMValueRef promise_ptr = ir_llvm_value(g, instruction->promise_ptr);
|
||||
LLVMValueRef align_val = LLVMConstInt(LLVMInt32Type(), get_coro_frame_align_bytes(g), false);
|
||||
LLVMValueRef null = LLVMConstIntToPtr(LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
|
||||
LLVMPointerType(LLVMInt8Type(), 0));
|
||||
LLVMValueRef params[] = {
|
||||
align_val,
|
||||
promise_ptr,
|
||||
null,
|
||||
null,
|
||||
};
|
||||
return LLVMBuildCall(g->builder, get_coro_id_fn_val(g), params, 4, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_alloc(CodeGen *g, IrExecutable *executable, IrInstructionCoroAlloc *instruction) {
|
||||
LLVMValueRef token = ir_llvm_value(g, instruction->coro_id);
|
||||
return LLVMBuildCall(g->builder, get_coro_alloc_fn_val(g), &token, 1, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_size(CodeGen *g, IrExecutable *executable, IrInstructionCoroSize *instruction) {
|
||||
return LLVMBuildCall(g->builder, get_coro_size_fn_val(g), nullptr, 0, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_begin(CodeGen *g, IrExecutable *executable, IrInstructionCoroBegin *instruction) {
|
||||
LLVMValueRef coro_id = ir_llvm_value(g, instruction->coro_id);
|
||||
LLVMValueRef coro_mem_ptr = ir_llvm_value(g, instruction->coro_mem_ptr);
|
||||
LLVMValueRef params[] = {
|
||||
coro_id,
|
||||
coro_mem_ptr,
|
||||
};
|
||||
return LLVMBuildCall(g->builder, get_coro_begin_fn_val(g), params, 2, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_alloc_fail(CodeGen *g, IrExecutable *executable,
|
||||
IrInstructionCoroAllocFail *instruction)
|
||||
{
|
||||
size_t err_code_ptr_arg_index = get_async_err_code_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
|
||||
LLVMValueRef err_code_ptr_val = LLVMGetParam(g->cur_fn_val, err_code_ptr_arg_index);
|
||||
LLVMValueRef err_code = ir_llvm_value(g, instruction->err_val);
|
||||
LLVMBuildStore(g->builder, err_code, err_code_ptr_val);
|
||||
|
||||
LLVMValueRef return_value;
|
||||
if (ir_want_runtime_safety(g, &instruction->base)) {
|
||||
return_value = LLVMConstNull(LLVMPointerType(LLVMInt8Type(), 0));
|
||||
} else {
|
||||
return_value = LLVMGetUndef(LLVMPointerType(LLVMInt8Type(), 0));
|
||||
}
|
||||
LLVMBuildRet(g->builder, return_value);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_suspend(CodeGen *g, IrExecutable *executable, IrInstructionCoroSuspend *instruction) {
|
||||
LLVMValueRef save_point;
|
||||
if (instruction->save_point == nullptr) {
|
||||
save_point = LLVMConstNull(ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()));
|
||||
} else {
|
||||
save_point = ir_llvm_value(g, instruction->save_point);
|
||||
}
|
||||
LLVMValueRef is_final = ir_llvm_value(g, instruction->is_final);
|
||||
LLVMValueRef params[] = {
|
||||
save_point,
|
||||
is_final,
|
||||
};
|
||||
return LLVMBuildCall(g->builder, get_coro_suspend_fn_val(g), params, 2, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_end(CodeGen *g, IrExecutable *executable, IrInstructionCoroEnd *instruction) {
|
||||
LLVMValueRef params[] = {
|
||||
LLVMConstNull(LLVMPointerType(LLVMInt8Type(), 0)),
|
||||
LLVMConstNull(LLVMInt1Type()),
|
||||
};
|
||||
return LLVMBuildCall(g->builder, get_coro_end_fn_val(g), params, 2, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_free(CodeGen *g, IrExecutable *executable, IrInstructionCoroFree *instruction) {
|
||||
LLVMValueRef coro_id = ir_llvm_value(g, instruction->coro_id);
|
||||
LLVMValueRef coro_handle = ir_llvm_value(g, instruction->coro_handle);
|
||||
LLVMValueRef params[] = {
|
||||
coro_id,
|
||||
coro_handle,
|
||||
};
|
||||
return LLVMBuildCall(g->builder, get_coro_free_fn_val(g), params, 2, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_resume(CodeGen *g, IrExecutable *executable, IrInstructionCoroResume *instruction) {
|
||||
LLVMValueRef awaiter_handle = ir_llvm_value(g, instruction->awaiter_handle);
|
||||
return LLVMBuildCall(g->builder, get_coro_resume_fn_val(g), &awaiter_handle, 1, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_save(CodeGen *g, IrExecutable *executable, IrInstructionCoroSave *instruction) {
|
||||
LLVMValueRef coro_handle = ir_llvm_value(g, instruction->coro_handle);
|
||||
return LLVMBuildCall(g->builder, get_coro_save_fn_val(g), &coro_handle, 1, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_promise(CodeGen *g, IrExecutable *executable, IrInstructionCoroPromise *instruction) {
|
||||
LLVMValueRef coro_handle = ir_llvm_value(g, instruction->coro_handle);
|
||||
LLVMValueRef params[] = {
|
||||
coro_handle,
|
||||
LLVMConstInt(LLVMInt32Type(), get_coro_frame_align_bytes(g), false),
|
||||
LLVMConstNull(LLVMInt1Type()),
|
||||
};
|
||||
LLVMValueRef uncasted_result = LLVMBuildCall(g->builder, get_coro_promise_fn_val(g), params, 3, "");
|
||||
return LLVMBuildBitCast(g->builder, uncasted_result, get_llvm_type(g, instruction->base.value.type), "");
|
||||
}
|
||||
|
||||
static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_fn_type_ref, ZigType *fn_type) {
|
||||
if (g->coro_alloc_helper_fn_val != nullptr)
|
||||
return g->coro_alloc_helper_fn_val;
|
||||
|
||||
assert(fn_type->id == ZigTypeIdFn);
|
||||
|
||||
ZigType *ptr_to_err_code_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false);
|
||||
|
||||
LLVMTypeRef alloc_raw_fn_type_ref = LLVMGetElementType(alloc_fn_type_ref);
|
||||
LLVMTypeRef *alloc_fn_arg_types = allocate<LLVMTypeRef>(LLVMCountParamTypes(alloc_raw_fn_type_ref));
|
||||
LLVMGetParamTypes(alloc_raw_fn_type_ref, alloc_fn_arg_types);
|
||||
|
||||
ZigList<LLVMTypeRef> arg_types = {};
|
||||
arg_types.append(alloc_fn_type_ref);
|
||||
if (g->have_err_ret_tracing) {
|
||||
arg_types.append(alloc_fn_arg_types[1]);
|
||||
}
|
||||
arg_types.append(alloc_fn_arg_types[g->have_err_ret_tracing ? 2 : 1]);
|
||||
arg_types.append(get_llvm_type(g, ptr_to_err_code_type));
|
||||
arg_types.append(g->builtin_types.entry_usize->llvm_type);
|
||||
|
||||
LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0),
|
||||
arg_types.items, arg_types.length, false);
|
||||
|
||||
Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_coro_alloc_helper"), false);
|
||||
LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
|
||||
LLVMSetLinkage(fn_val, LLVMInternalLinkage);
|
||||
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
|
||||
addLLVMFnAttr(fn_val, "nounwind");
|
||||
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
|
||||
addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");
|
||||
|
||||
LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
|
||||
LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder);
|
||||
ZigFn *prev_cur_fn = g->cur_fn;
|
||||
LLVMValueRef prev_cur_fn_val = g->cur_fn_val;
|
||||
|
||||
LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry");
|
||||
LLVMPositionBuilderAtEnd(g->builder, entry_block);
|
||||
ZigLLVMClearCurrentDebugLocation(g->builder);
|
||||
g->cur_fn = nullptr;
|
||||
g->cur_fn_val = fn_val;
|
||||
|
||||
LLVMValueRef sret_ptr = LLVMBuildAlloca(g->builder, LLVMGetElementType(alloc_fn_arg_types[0]), "");
|
||||
|
||||
size_t next_arg = 0;
|
||||
LLVMValueRef realloc_fn_val = LLVMGetParam(fn_val, next_arg);
|
||||
next_arg += 1;
|
||||
|
||||
LLVMValueRef stack_trace_val;
|
||||
if (g->have_err_ret_tracing) {
|
||||
stack_trace_val = LLVMGetParam(fn_val, next_arg);
|
||||
next_arg += 1;
|
||||
}
|
||||
|
||||
LLVMValueRef allocator_val = LLVMGetParam(fn_val, next_arg);
|
||||
next_arg += 1;
|
||||
LLVMValueRef err_code_ptr = LLVMGetParam(fn_val, next_arg);
|
||||
next_arg += 1;
|
||||
LLVMValueRef coro_size = LLVMGetParam(fn_val, next_arg);
|
||||
next_arg += 1;
|
||||
LLVMValueRef alignment_val = LLVMConstInt(g->builtin_types.entry_u29->llvm_type,
|
||||
get_coro_frame_align_bytes(g), false);
|
||||
|
||||
ConstExprValue *zero_array = create_const_str_lit(g, buf_create_from_str(""));
|
||||
ConstExprValue *undef_slice_zero = create_const_slice(g, zero_array, 0, 0, false);
|
||||
render_const_val(g, undef_slice_zero, "");
|
||||
render_const_val_global(g, undef_slice_zero, "");
|
||||
|
||||
ZigList<LLVMValueRef> args = {};
|
||||
args.append(sret_ptr);
|
||||
if (g->have_err_ret_tracing) {
|
||||
args.append(stack_trace_val);
|
||||
}
|
||||
args.append(allocator_val);
|
||||
args.append(undef_slice_zero->global_refs->llvm_global);
|
||||
args.append(LLVMGetUndef(g->builtin_types.entry_u29->llvm_type));
|
||||
args.append(coro_size);
|
||||
args.append(alignment_val);
|
||||
LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, realloc_fn_val, args.items, args.length,
|
||||
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
|
||||
set_call_instr_sret(g, call_instruction);
|
||||
LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_err_index, "");
|
||||
LLVMValueRef err_val = LLVMBuildLoad(g->builder, err_val_ptr, "");
|
||||
LLVMBuildStore(g->builder, err_val, err_code_ptr);
|
||||
LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, LLVMConstNull(LLVMTypeOf(err_val)), "");
|
||||
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(fn_val, "AllocOk");
|
||||
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(fn_val, "AllocFail");
|
||||
LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, ok_block);
|
||||
LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_payload_index, "");
|
||||
ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, false, false,
|
||||
PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false);
|
||||
ZigType *slice_type = get_slice_type(g, u8_ptr_type);
|
||||
size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;
|
||||
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, payload_ptr, ptr_field_index, "");
|
||||
LLVMValueRef ptr_val = LLVMBuildLoad(g->builder, ptr_field_ptr, "");
|
||||
LLVMBuildRet(g->builder, ptr_val);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, fail_block);
|
||||
LLVMBuildRet(g->builder, LLVMConstNull(LLVMPointerType(LLVMInt8Type(), 0)));
|
||||
|
||||
g->cur_fn = prev_cur_fn;
|
||||
g->cur_fn_val = prev_cur_fn_val;
|
||||
LLVMPositionBuilderAtEnd(g->builder, prev_block);
|
||||
if (!g->strip_debug_symbols) {
|
||||
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
|
||||
}
|
||||
|
||||
g->coro_alloc_helper_fn_val = fn_val;
|
||||
return fn_val;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_coro_alloc_helper(CodeGen *g, IrExecutable *executable,
|
||||
IrInstructionCoroAllocHelper *instruction)
|
||||
{
|
||||
LLVMValueRef realloc_fn = ir_llvm_value(g, instruction->realloc_fn);
|
||||
LLVMValueRef coro_size = ir_llvm_value(g, instruction->coro_size);
|
||||
LLVMValueRef fn_val = get_coro_alloc_helper_fn_val(g, LLVMTypeOf(realloc_fn), instruction->realloc_fn->value.type);
|
||||
size_t err_code_ptr_arg_index = get_async_err_code_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
|
||||
size_t allocator_arg_index = get_async_allocator_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
|
||||
|
||||
ZigList<LLVMValueRef> params = {};
|
||||
params.append(realloc_fn);
|
||||
uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, g->cur_fn);
|
||||
if (err_ret_trace_arg_index != UINT32_MAX) {
|
||||
params.append(LLVMGetParam(g->cur_fn_val, err_ret_trace_arg_index));
|
||||
}
|
||||
params.append(LLVMGetParam(g->cur_fn_val, allocator_arg_index));
|
||||
params.append(LLVMGetParam(g->cur_fn_val, err_code_ptr_arg_index));
|
||||
params.append(coro_size);
|
||||
|
||||
return ZigLLVMBuildCall(g->builder, fn_val, params.items, params.length,
|
||||
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
|
||||
IrInstructionAtomicRmw *instruction)
|
||||
{
|
||||
@ -5402,19 +4798,6 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutable *executable,
|
||||
return load_inst;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *executable,
|
||||
IrInstructionMergeErrRetTraces *instruction)
|
||||
{
|
||||
assert(g->have_err_ret_tracing);
|
||||
|
||||
LLVMValueRef src_trace_ptr = ir_llvm_value(g, instruction->src_err_ret_trace_ptr);
|
||||
LLVMValueRef dest_trace_ptr = ir_llvm_value(g, instruction->dest_err_ret_trace_ptr);
|
||||
|
||||
LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
|
||||
ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_mark_err_ret_trace_ptr(CodeGen *g, IrExecutable *executable,
|
||||
IrInstructionMarkErrRetTracePtr *instruction)
|
||||
{
|
||||
@ -5559,7 +4942,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||
case IrInstructionIdSetRuntimeSafety:
|
||||
case IrInstructionIdSetFloatMode:
|
||||
case IrInstructionIdArrayType:
|
||||
case IrInstructionIdPromiseType:
|
||||
case IrInstructionIdSliceType:
|
||||
case IrInstructionIdSizeOf:
|
||||
case IrInstructionIdSwitchTarget:
|
||||
@ -5599,8 +4981,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||
case IrInstructionIdTagType:
|
||||
case IrInstructionIdExport:
|
||||
case IrInstructionIdErrorUnion:
|
||||
case IrInstructionIdPromiseResultType:
|
||||
case IrInstructionIdAwaitBookkeeping:
|
||||
case IrInstructionIdAddImplicitReturnType:
|
||||
case IrInstructionIdIntCast:
|
||||
case IrInstructionIdFloatCast:
|
||||
@ -5757,40 +5137,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
||||
return ir_render_error_return_trace(g, executable, (IrInstructionErrorReturnTrace *)instruction);
|
||||
case IrInstructionIdCancel:
|
||||
return ir_render_cancel(g, executable, (IrInstructionCancel *)instruction);
|
||||
case IrInstructionIdGetImplicitAllocator:
|
||||
return ir_render_get_implicit_allocator(g, executable, (IrInstructionGetImplicitAllocator *)instruction);
|
||||
case IrInstructionIdCoroId:
|
||||
return ir_render_coro_id(g, executable, (IrInstructionCoroId *)instruction);
|
||||
case IrInstructionIdCoroAlloc:
|
||||
return ir_render_coro_alloc(g, executable, (IrInstructionCoroAlloc *)instruction);
|
||||
case IrInstructionIdCoroSize:
|
||||
return ir_render_coro_size(g, executable, (IrInstructionCoroSize *)instruction);
|
||||
case IrInstructionIdCoroBegin:
|
||||
return ir_render_coro_begin(g, executable, (IrInstructionCoroBegin *)instruction);
|
||||
case IrInstructionIdCoroAllocFail:
|
||||
return ir_render_coro_alloc_fail(g, executable, (IrInstructionCoroAllocFail *)instruction);
|
||||
case IrInstructionIdCoroSuspend:
|
||||
return ir_render_coro_suspend(g, executable, (IrInstructionCoroSuspend *)instruction);
|
||||
case IrInstructionIdCoroEnd:
|
||||
return ir_render_coro_end(g, executable, (IrInstructionCoroEnd *)instruction);
|
||||
case IrInstructionIdCoroFree:
|
||||
return ir_render_coro_free(g, executable, (IrInstructionCoroFree *)instruction);
|
||||
case IrInstructionIdCoroResume:
|
||||
return ir_render_coro_resume(g, executable, (IrInstructionCoroResume *)instruction);
|
||||
case IrInstructionIdCoroSave:
|
||||
return ir_render_coro_save(g, executable, (IrInstructionCoroSave *)instruction);
|
||||
case IrInstructionIdCoroPromise:
|
||||
return ir_render_coro_promise(g, executable, (IrInstructionCoroPromise *)instruction);
|
||||
case IrInstructionIdCoroAllocHelper:
|
||||
return ir_render_coro_alloc_helper(g, executable, (IrInstructionCoroAllocHelper *)instruction);
|
||||
case IrInstructionIdAtomicRmw:
|
||||
return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction);
|
||||
case IrInstructionIdAtomicLoad:
|
||||
return ir_render_atomic_load(g, executable, (IrInstructionAtomicLoad *)instruction);
|
||||
case IrInstructionIdSaveErrRetAddr:
|
||||
return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction);
|
||||
case IrInstructionIdMergeErrRetTraces:
|
||||
return ir_render_merge_err_ret_traces(g, executable, (IrInstructionMergeErrRetTraces *)instruction);
|
||||
case IrInstructionIdMarkErrRetTracePtr:
|
||||
return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);
|
||||
case IrInstructionIdFloatOp:
|
||||
@ -6008,7 +5360,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
|
||||
case ZigTypeIdPointer:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdOptional:
|
||||
case ZigTypeIdPromise:
|
||||
{
|
||||
LLVMValueRef ptr_val = gen_const_val(g, const_val, "");
|
||||
LLVMValueRef ptr_size_int_val = LLVMConstPtrToInt(ptr_val, g->builtin_types.entry_usize->llvm_type);
|
||||
@ -6591,7 +5942,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
|
||||
case ZigTypeIdBoundFn:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOpaque:
|
||||
case ZigTypeIdPromise:
|
||||
zig_unreachable();
|
||||
|
||||
}
|
||||
@ -7294,13 +6644,6 @@ static void define_builtin_types(CodeGen *g) {
|
||||
|
||||
g->primitive_type_table.put(&entry->name, entry);
|
||||
}
|
||||
{
|
||||
ZigType *entry = get_promise_type(g, nullptr);
|
||||
g->primitive_type_table.put(&entry->name, entry);
|
||||
entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
|
||||
entry->abi_align = g->builtin_types.entry_usize->abi_align;
|
||||
entry->abi_size = g->builtin_types.entry_usize->abi_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7729,7 +7072,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||
" BoundFn: Fn,\n"
|
||||
" ArgTuple: void,\n"
|
||||
" Opaque: void,\n"
|
||||
" Promise: Promise,\n"
|
||||
" Vector: Vector,\n"
|
||||
" EnumLiteral: void,\n"
|
||||
"\n\n"
|
||||
@ -7842,14 +7184,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||
" is_generic: bool,\n"
|
||||
" is_var_args: bool,\n"
|
||||
" return_type: ?type,\n"
|
||||
" async_allocator_type: ?type,\n"
|
||||
" args: []FnArg,\n"
|
||||
" };\n"
|
||||
"\n"
|
||||
" pub const Promise = struct {\n"
|
||||
" child: ?type,\n"
|
||||
" };\n"
|
||||
"\n"
|
||||
" pub const Vector = struct {\n"
|
||||
" len: comptime_int,\n"
|
||||
" child: type,\n"
|
||||
@ -8998,7 +8335,6 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdErrorUnion:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdPromise:
|
||||
zig_unreachable();
|
||||
case ZigTypeIdVoid:
|
||||
case ZigTypeIdUnreachable:
|
||||
@ -9182,7 +8518,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
|
||||
case ZigTypeIdUndefined:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdPromise:
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
@ -9349,7 +8684,6 @@ static void gen_h_file(CodeGen *g) {
|
||||
case ZigTypeIdArgTuple:
|
||||
case ZigTypeIdOptional:
|
||||
case ZigTypeIdFn:
|
||||
case ZigTypeIdPromise:
|
||||
case ZigTypeIdVector:
|
||||
zig_unreachable();
|
||||
case ZigTypeIdEnum:
|
||||
|
1539
src/ir.cpp
1539
src/ir.cpp
File diff suppressed because it is too large
Load Diff
190
src/ir_print.cpp
190
src/ir_print.cpp
@ -257,13 +257,7 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
|
||||
|
||||
static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instruction) {
|
||||
if (call_instruction->is_async) {
|
||||
fprintf(irp->f, "async");
|
||||
if (call_instruction->async_allocator != nullptr) {
|
||||
fprintf(irp->f, "<");
|
||||
ir_print_other_instruction(irp, call_instruction->async_allocator);
|
||||
fprintf(irp->f, ">");
|
||||
}
|
||||
fprintf(irp->f, " ");
|
||||
fprintf(irp->f, "async ");
|
||||
}
|
||||
if (call_instruction->fn_entry) {
|
||||
fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
|
||||
@ -284,13 +278,7 @@ static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instructi
|
||||
|
||||
static void ir_print_call_gen(IrPrint *irp, IrInstructionCallGen *call_instruction) {
|
||||
if (call_instruction->is_async) {
|
||||
fprintf(irp->f, "async");
|
||||
if (call_instruction->async_allocator != nullptr) {
|
||||
fprintf(irp->f, "<");
|
||||
ir_print_other_instruction(irp, call_instruction->async_allocator);
|
||||
fprintf(irp->f, ">");
|
||||
}
|
||||
fprintf(irp->f, " ");
|
||||
fprintf(irp->f, "async ");
|
||||
}
|
||||
if (call_instruction->fn_entry) {
|
||||
fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
|
||||
@ -477,14 +465,6 @@ static void ir_print_array_type(IrPrint *irp, IrInstructionArrayType *instructio
|
||||
ir_print_other_instruction(irp, instruction->child_type);
|
||||
}
|
||||
|
||||
static void ir_print_promise_type(IrPrint *irp, IrInstructionPromiseType *instruction) {
|
||||
fprintf(irp->f, "promise");
|
||||
if (instruction->payload_type != nullptr) {
|
||||
fprintf(irp->f, "->");
|
||||
ir_print_other_instruction(irp, instruction->payload_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_print_slice_type(IrPrint *irp, IrInstructionSliceType *instruction) {
|
||||
const char *const_kw = instruction->is_const ? "const " : "";
|
||||
fprintf(irp->f, "[]%s", const_kw);
|
||||
@ -1396,105 +1376,6 @@ static void ir_print_cancel(IrPrint *irp, IrInstructionCancel *instruction) {
|
||||
ir_print_other_instruction(irp, instruction->target);
|
||||
}
|
||||
|
||||
static void ir_print_get_implicit_allocator(IrPrint *irp, IrInstructionGetImplicitAllocator *instruction) {
|
||||
fprintf(irp->f, "@getImplicitAllocator(");
|
||||
switch (instruction->id) {
|
||||
case ImplicitAllocatorIdArg:
|
||||
fprintf(irp->f, "Arg");
|
||||
break;
|
||||
case ImplicitAllocatorIdLocalVar:
|
||||
fprintf(irp->f, "LocalVar");
|
||||
break;
|
||||
}
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_id(IrPrint *irp, IrInstructionCoroId *instruction) {
|
||||
fprintf(irp->f, "@coroId(");
|
||||
ir_print_other_instruction(irp, instruction->promise_ptr);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_alloc(IrPrint *irp, IrInstructionCoroAlloc *instruction) {
|
||||
fprintf(irp->f, "@coroAlloc(");
|
||||
ir_print_other_instruction(irp, instruction->coro_id);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_size(IrPrint *irp, IrInstructionCoroSize *instruction) {
|
||||
fprintf(irp->f, "@coroSize()");
|
||||
}
|
||||
|
||||
static void ir_print_coro_begin(IrPrint *irp, IrInstructionCoroBegin *instruction) {
|
||||
fprintf(irp->f, "@coroBegin(");
|
||||
ir_print_other_instruction(irp, instruction->coro_id);
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->coro_mem_ptr);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_alloc_fail(IrPrint *irp, IrInstructionCoroAllocFail *instruction) {
|
||||
fprintf(irp->f, "@coroAllocFail(");
|
||||
ir_print_other_instruction(irp, instruction->err_val);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_suspend(IrPrint *irp, IrInstructionCoroSuspend *instruction) {
|
||||
fprintf(irp->f, "@coroSuspend(");
|
||||
if (instruction->save_point != nullptr) {
|
||||
ir_print_other_instruction(irp, instruction->save_point);
|
||||
} else {
|
||||
fprintf(irp->f, "null");
|
||||
}
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->is_final);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_end(IrPrint *irp, IrInstructionCoroEnd *instruction) {
|
||||
fprintf(irp->f, "@coroEnd()");
|
||||
}
|
||||
|
||||
static void ir_print_coro_free(IrPrint *irp, IrInstructionCoroFree *instruction) {
|
||||
fprintf(irp->f, "@coroFree(");
|
||||
ir_print_other_instruction(irp, instruction->coro_id);
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->coro_handle);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_resume(IrPrint *irp, IrInstructionCoroResume *instruction) {
|
||||
fprintf(irp->f, "@coroResume(");
|
||||
ir_print_other_instruction(irp, instruction->awaiter_handle);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_save(IrPrint *irp, IrInstructionCoroSave *instruction) {
|
||||
fprintf(irp->f, "@coroSave(");
|
||||
ir_print_other_instruction(irp, instruction->coro_handle);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_promise(IrPrint *irp, IrInstructionCoroPromise *instruction) {
|
||||
fprintf(irp->f, "@coroPromise(");
|
||||
ir_print_other_instruction(irp, instruction->coro_handle);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_promise_result_type(IrPrint *irp, IrInstructionPromiseResultType *instruction) {
|
||||
fprintf(irp->f, "@PromiseResultType(");
|
||||
ir_print_other_instruction(irp, instruction->promise_type);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_coro_alloc_helper(IrPrint *irp, IrInstructionCoroAllocHelper *instruction) {
|
||||
fprintf(irp->f, "@coroAllocHelper(");
|
||||
ir_print_other_instruction(irp, instruction->realloc_fn);
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->coro_size);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_atomic_rmw(IrPrint *irp, IrInstructionAtomicRmw *instruction) {
|
||||
fprintf(irp->f, "@atomicRmw(");
|
||||
if (instruction->operand_type != nullptr) {
|
||||
@ -1539,12 +1420,6 @@ static void ir_print_atomic_load(IrPrint *irp, IrInstructionAtomicLoad *instruct
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_await_bookkeeping(IrPrint *irp, IrInstructionAwaitBookkeeping *instruction) {
|
||||
fprintf(irp->f, "@awaitBookkeeping(");
|
||||
ir_print_other_instruction(irp, instruction->promise_result_type);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_save_err_ret_addr(IrPrint *irp, IrInstructionSaveErrRetAddr *instruction) {
|
||||
fprintf(irp->f, "@saveErrRetAddr()");
|
||||
}
|
||||
@ -1555,16 +1430,6 @@ static void ir_print_add_implicit_return_type(IrPrint *irp, IrInstructionAddImpl
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_merge_err_ret_traces(IrPrint *irp, IrInstructionMergeErrRetTraces *instruction) {
|
||||
fprintf(irp->f, "@mergeErrRetTraces(");
|
||||
ir_print_other_instruction(irp, instruction->coro_promise_ptr);
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->src_err_ret_trace_ptr);
|
||||
fprintf(irp->f, ",");
|
||||
ir_print_other_instruction(irp, instruction->dest_err_ret_trace_ptr);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_mark_err_ret_trace_ptr(IrPrint *irp, IrInstructionMarkErrRetTracePtr *instruction) {
|
||||
fprintf(irp->f, "@markErrRetTracePtr(");
|
||||
ir_print_other_instruction(irp, instruction->err_ret_trace_ptr);
|
||||
@ -1727,9 +1592,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdArrayType:
|
||||
ir_print_array_type(irp, (IrInstructionArrayType *)instruction);
|
||||
break;
|
||||
case IrInstructionIdPromiseType:
|
||||
ir_print_promise_type(irp, (IrInstructionPromiseType *)instruction);
|
||||
break;
|
||||
case IrInstructionIdSliceType:
|
||||
ir_print_slice_type(irp, (IrInstructionSliceType *)instruction);
|
||||
break;
|
||||
@ -2033,63 +1895,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
case IrInstructionIdCancel:
|
||||
ir_print_cancel(irp, (IrInstructionCancel *)instruction);
|
||||
break;
|
||||
case IrInstructionIdGetImplicitAllocator:
|
||||
ir_print_get_implicit_allocator(irp, (IrInstructionGetImplicitAllocator *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroId:
|
||||
ir_print_coro_id(irp, (IrInstructionCoroId *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroAlloc:
|
||||
ir_print_coro_alloc(irp, (IrInstructionCoroAlloc *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroSize:
|
||||
ir_print_coro_size(irp, (IrInstructionCoroSize *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroBegin:
|
||||
ir_print_coro_begin(irp, (IrInstructionCoroBegin *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroAllocFail:
|
||||
ir_print_coro_alloc_fail(irp, (IrInstructionCoroAllocFail *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroSuspend:
|
||||
ir_print_coro_suspend(irp, (IrInstructionCoroSuspend *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroEnd:
|
||||
ir_print_coro_end(irp, (IrInstructionCoroEnd *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroFree:
|
||||
ir_print_coro_free(irp, (IrInstructionCoroFree *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroResume:
|
||||
ir_print_coro_resume(irp, (IrInstructionCoroResume *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroSave:
|
||||
ir_print_coro_save(irp, (IrInstructionCoroSave *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroAllocHelper:
|
||||
ir_print_coro_alloc_helper(irp, (IrInstructionCoroAllocHelper *)instruction);
|
||||
break;
|
||||
case IrInstructionIdAtomicRmw:
|
||||
ir_print_atomic_rmw(irp, (IrInstructionAtomicRmw *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCoroPromise:
|
||||
ir_print_coro_promise(irp, (IrInstructionCoroPromise *)instruction);
|
||||
break;
|
||||
case IrInstructionIdPromiseResultType:
|
||||
ir_print_promise_result_type(irp, (IrInstructionPromiseResultType *)instruction);
|
||||
break;
|
||||
case IrInstructionIdAwaitBookkeeping:
|
||||
ir_print_await_bookkeeping(irp, (IrInstructionAwaitBookkeeping *)instruction);
|
||||
break;
|
||||
case IrInstructionIdSaveErrRetAddr:
|
||||
ir_print_save_err_ret_addr(irp, (IrInstructionSaveErrRetAddr *)instruction);
|
||||
break;
|
||||
case IrInstructionIdAddImplicitReturnType:
|
||||
ir_print_add_implicit_return_type(irp, (IrInstructionAddImplicitReturnType *)instruction);
|
||||
break;
|
||||
case IrInstructionIdMergeErrRetTraces:
|
||||
ir_print_merge_err_ret_traces(irp, (IrInstructionMergeErrRetTraces *)instruction);
|
||||
break;
|
||||
case IrInstructionIdMarkErrRetTracePtr:
|
||||
ir_print_mark_err_ret_trace_ptr(irp, (IrInstructionMarkErrRetTracePtr *)instruction);
|
||||
break;
|
||||
|
@ -282,9 +282,6 @@ static AstNode *ast_parse_prefix_op_expr(
|
||||
case NodeTypeAwaitExpr:
|
||||
right = &prefix->data.await_expr.expr;
|
||||
break;
|
||||
case NodeTypePromiseType:
|
||||
right = &prefix->data.promise_type.payload_type;
|
||||
break;
|
||||
case NodeTypeArrayType:
|
||||
right = &prefix->data.array_type.child_type;
|
||||
break;
|
||||
@ -1643,10 +1640,6 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
|
||||
if (null != nullptr)
|
||||
return ast_create_node(pc, NodeTypeNullLiteral, null);
|
||||
|
||||
Token *promise = eat_token_if(pc, TokenIdKeywordPromise);
|
||||
if (promise != nullptr)
|
||||
return ast_create_node(pc, NodeTypePromiseType, promise);
|
||||
|
||||
Token *true_token = eat_token_if(pc, TokenIdKeywordTrue);
|
||||
if (true_token != nullptr) {
|
||||
AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token);
|
||||
@ -2042,11 +2035,6 @@ static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) {
|
||||
}
|
||||
if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
|
||||
res.cc = CallingConventionAsync;
|
||||
if (eat_token_if(pc, TokenIdCmpLessThan) == nullptr)
|
||||
return Optional<AstNodeFnProto>::some(res);
|
||||
|
||||
res.async_allocator_type = ast_expect(pc, ast_parse_type_expr);
|
||||
expect_token(pc, TokenIdCmpGreaterThan);
|
||||
return Optional<AstNodeFnProto>::some(res);
|
||||
}
|
||||
|
||||
@ -2533,16 +2521,6 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
|
||||
return res;
|
||||
}
|
||||
|
||||
Token *promise = eat_token_if(pc, TokenIdKeywordPromise);
|
||||
if (promise != nullptr) {
|
||||
if (eat_token_if(pc, TokenIdArrow) != nullptr) {
|
||||
AstNode *res = ast_create_node(pc, NodeTypePromiseType, promise);
|
||||
return res;
|
||||
}
|
||||
|
||||
put_back_token(pc);
|
||||
}
|
||||
|
||||
AstNode *array = ast_parse_array_type_start(pc);
|
||||
if (array != nullptr) {
|
||||
assert(array->type == NodeTypeArrayType);
|
||||
@ -2680,11 +2658,6 @@ static AstNode *ast_parse_async_prefix(ParseContext *pc) {
|
||||
AstNode *res = ast_create_node(pc, NodeTypeFnCallExpr, async);
|
||||
res->data.fn_call_expr.is_async = true;
|
||||
res->data.fn_call_expr.seen = false;
|
||||
if (eat_token_if(pc, TokenIdCmpLessThan) != nullptr) {
|
||||
AstNode *prefix_expr = ast_expect(pc, ast_parse_prefix_expr);
|
||||
expect_token(pc, TokenIdCmpGreaterThan);
|
||||
res->data.fn_call_expr.async_allocator = prefix_expr;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -2858,7 +2831,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
|
||||
visit_node_list(&node->data.fn_proto.params, visit, context);
|
||||
visit_field(&node->data.fn_proto.align_expr, visit, context);
|
||||
visit_field(&node->data.fn_proto.section_expr, visit, context);
|
||||
visit_field(&node->data.fn_proto.async_allocator_type, visit, context);
|
||||
break;
|
||||
case NodeTypeFnDef:
|
||||
visit_field(&node->data.fn_def.fn_proto, visit, context);
|
||||
@ -2918,7 +2890,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
|
||||
case NodeTypeFnCallExpr:
|
||||
visit_field(&node->data.fn_call_expr.fn_ref_expr, visit, context);
|
||||
visit_node_list(&node->data.fn_call_expr.params, visit, context);
|
||||
visit_field(&node->data.fn_call_expr.async_allocator, visit, context);
|
||||
break;
|
||||
case NodeTypeArrayAccessExpr:
|
||||
visit_field(&node->data.array_access_expr.array_ref_expr, visit, context);
|
||||
@ -3034,9 +3005,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
|
||||
case NodeTypeInferredArrayType:
|
||||
visit_field(&node->data.array_type.child_type, visit, context);
|
||||
break;
|
||||
case NodeTypePromiseType:
|
||||
visit_field(&node->data.promise_type.payload_type, visit, context);
|
||||
break;
|
||||
case NodeTypeErrorType:
|
||||
// none
|
||||
break;
|
||||
|
@ -136,7 +136,6 @@ static const struct ZigKeyword zig_keywords[] = {
|
||||
{"or", TokenIdKeywordOr},
|
||||
{"orelse", TokenIdKeywordOrElse},
|
||||
{"packed", TokenIdKeywordPacked},
|
||||
{"promise", TokenIdKeywordPromise},
|
||||
{"pub", TokenIdKeywordPub},
|
||||
{"resume", TokenIdKeywordResume},
|
||||
{"return", TokenIdKeywordReturn},
|
||||
@ -1558,7 +1557,6 @@ const char * token_name(TokenId id) {
|
||||
case TokenIdKeywordOr: return "or";
|
||||
case TokenIdKeywordOrElse: return "orelse";
|
||||
case TokenIdKeywordPacked: return "packed";
|
||||
case TokenIdKeywordPromise: return "promise";
|
||||
case TokenIdKeywordPub: return "pub";
|
||||
case TokenIdKeywordReturn: return "return";
|
||||
case TokenIdKeywordLinkSection: return "linksection";
|
||||
|
@ -81,7 +81,6 @@ enum TokenId {
|
||||
TokenIdKeywordOr,
|
||||
TokenIdKeywordOrElse,
|
||||
TokenIdKeywordPacked,
|
||||
TokenIdKeywordPromise,
|
||||
TokenIdKeywordPub,
|
||||
TokenIdKeywordResume,
|
||||
TokenIdKeywordReturn,
|
||||
|
@ -328,9 +328,6 @@ pub fn formatType(
|
||||
try output(context, "error.");
|
||||
return output(context, @errorName(value));
|
||||
},
|
||||
.Promise => {
|
||||
return format(context, Errors, output, "promise@{x}", @ptrToInt(value));
|
||||
},
|
||||
.Enum => {
|
||||
if (comptime std.meta.trait.hasFn("format")(T)) {
|
||||
return value.format(fmt, options, context, Errors, output);
|
||||
|
@ -560,7 +560,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
|
||||
builtin.TypeId.Bool => return autoHash(@boolToInt(key), rng, HashInt),
|
||||
builtin.TypeId.Enum => return autoHash(@enumToInt(key), rng, HashInt),
|
||||
builtin.TypeId.ErrorSet => return autoHash(@errorToInt(key), rng, HashInt),
|
||||
builtin.TypeId.Promise, builtin.TypeId.Fn => return autoHash(@ptrToInt(key), rng, HashInt),
|
||||
builtin.TypeId.Fn => return autoHash(@ptrToInt(key), rng, HashInt),
|
||||
|
||||
builtin.TypeId.BoundFn,
|
||||
builtin.TypeId.ComptimeFloat,
|
||||
|
@ -104,8 +104,7 @@ pub fn Child(comptime T: type) type {
|
||||
TypeId.Array => |info| info.child,
|
||||
TypeId.Pointer => |info| info.child,
|
||||
TypeId.Optional => |info| info.child,
|
||||
TypeId.Promise => |info| if (info.child) |child| child else null,
|
||||
else => @compileError("Expected promise, pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"),
|
||||
else => @compileError("Expected pointer, optional, or array type, " ++ "found '" ++ @typeName(T) ++ "'"),
|
||||
};
|
||||
}
|
||||
|
||||
@ -114,7 +113,6 @@ test "std.meta.Child" {
|
||||
testing.expect(Child(*u8) == u8);
|
||||
testing.expect(Child([]u8) == u8);
|
||||
testing.expect(Child(?u8) == u8);
|
||||
testing.expect(Child(promise->u8) == u8);
|
||||
}
|
||||
|
||||
pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout {
|
||||
|
@ -45,7 +45,6 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
|
||||
TypeId.EnumLiteral,
|
||||
TypeId.Enum,
|
||||
TypeId.Fn,
|
||||
TypeId.Promise,
|
||||
TypeId.Vector,
|
||||
TypeId.ErrorSet,
|
||||
=> {
|
||||
|
@ -39,11 +39,11 @@ comptime {
|
||||
_ = @import("behavior/bugs/828.zig");
|
||||
_ = @import("behavior/bugs/920.zig");
|
||||
_ = @import("behavior/byval_arg_var.zig");
|
||||
_ = @import("behavior/cancel.zig");
|
||||
//_ = @import("behavior/cancel.zig");
|
||||
_ = @import("behavior/cast.zig");
|
||||
_ = @import("behavior/const_slice_child.zig");
|
||||
_ = @import("behavior/coroutine_await_struct.zig");
|
||||
_ = @import("behavior/coroutines.zig");
|
||||
//_ = @import("behavior/coroutine_await_struct.zig");
|
||||
//_ = @import("behavior/coroutines.zig");
|
||||
_ = @import("behavior/defer.zig");
|
||||
_ = @import("behavior/enum.zig");
|
||||
_ = @import("behavior/enum_with_members.zig");
|
||||
|
@ -116,21 +116,6 @@ fn testOptional() void {
|
||||
expect(null_info.Optional.child == void);
|
||||
}
|
||||
|
||||
test "type info: promise info" {
|
||||
testPromise();
|
||||
comptime testPromise();
|
||||
}
|
||||
|
||||
fn testPromise() void {
|
||||
const null_promise_info = @typeInfo(promise);
|
||||
expect(TypeId(null_promise_info) == TypeId.Promise);
|
||||
expect(null_promise_info.Promise.child == null);
|
||||
|
||||
const promise_info = @typeInfo(promise->usize);
|
||||
expect(TypeId(promise_info) == TypeId.Promise);
|
||||
expect(promise_info.Promise.child.? == usize);
|
||||
}
|
||||
|
||||
test "type info: error set, error union info" {
|
||||
testErrorSet();
|
||||
comptime testErrorSet();
|
||||
@ -192,11 +177,11 @@ fn testUnion() void {
|
||||
expect(TypeId(typeinfo_info) == TypeId.Union);
|
||||
expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
|
||||
expect(typeinfo_info.Union.tag_type.? == TypeId);
|
||||
expect(typeinfo_info.Union.fields.len == 25);
|
||||
expect(typeinfo_info.Union.fields.len == 24);
|
||||
expect(typeinfo_info.Union.fields[4].enum_field != null);
|
||||
expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
|
||||
expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
|
||||
expect(typeinfo_info.Union.decls.len == 21);
|
||||
expect(typeinfo_info.Union.decls.len == 20);
|
||||
|
||||
const TestNoTagUnion = union {
|
||||
Foo: void,
|
||||
@ -265,7 +250,6 @@ fn testFunction() void {
|
||||
expect(fn_info.Fn.args.len == 2);
|
||||
expect(fn_info.Fn.is_var_args);
|
||||
expect(fn_info.Fn.return_type == null);
|
||||
expect(fn_info.Fn.async_allocator_type == null);
|
||||
|
||||
const test_instance: TestStruct = undefined;
|
||||
const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
|
||||
|
Loading…
x
Reference in New Issue
Block a user