remove @newStackCall
from zig
This commit is contained in:
parent
343987cd05
commit
71b7f4b47f
@ -6904,6 +6904,41 @@ pub const CallOptions = struct {
|
||||
};
|
||||
};
|
||||
{#code_end#}
|
||||
|
||||
{#header_open|Calling with a New Stack#}
|
||||
<p>
|
||||
When the {#syntax#}stack{#endsyntax#} option is provided, instead of using the same stack as the caller, the function uses the provided stack.
|
||||
</p>
|
||||
{#code_begin|test|new_stack_call#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
var new_stack_bytes: [1024]u8 align(16) = undefined;
|
||||
|
||||
test "calling a function with a new stack" {
|
||||
const arg = 1234;
|
||||
|
||||
const a = @call(.{.stack = new_stack_bytes[0..512]}, targetFunction, .{arg});
|
||||
const b = @call(.{.stack = new_stack_bytes[512..]}, targetFunction, .{arg});
|
||||
_ = targetFunction(arg);
|
||||
|
||||
assert(arg == 1234);
|
||||
assert(a < b);
|
||||
}
|
||||
|
||||
fn targetFunction(x: i32) usize {
|
||||
assert(x == 1234);
|
||||
|
||||
var local_variable: i32 = 42;
|
||||
const ptr = &local_variable;
|
||||
ptr.* += 1;
|
||||
|
||||
assert(local_variable == 43);
|
||||
return @ptrToInt(ptr);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@cDefine#}
|
||||
@ -7649,48 +7684,6 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@newStackCall#}
|
||||
<pre>{#syntax#}@newStackCall(new_stack: []align(target_stack_align) u8, function: var, args: ...) var{#endsyntax#}</pre>
|
||||
<p>
|
||||
This calls a function, in the same way that invoking an expression with parentheses does. However,
|
||||
instead of using the same stack as the caller, the function uses the stack provided in the {#syntax#}new_stack{#endsyntax#}
|
||||
parameter.
|
||||
</p>
|
||||
<p>
|
||||
The new stack must be aligned to {#syntax#}target_stack_align{#endsyntax#} bytes. This is a target-specific
|
||||
number. A safe value that will work on all targets is {#syntax#}16{#endsyntax#}. This value can
|
||||
also be obtained by using {#link|@sizeOf#} on the {#link|@Frame#} type of {#link|Async Functions#}.
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
var new_stack_bytes: [1024]u8 align(16) = undefined;
|
||||
|
||||
test "calling a function with a new stack" {
|
||||
const arg = 1234;
|
||||
|
||||
const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
|
||||
const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
|
||||
_ = targetFunction(arg);
|
||||
|
||||
assert(arg == 1234);
|
||||
assert(a < b);
|
||||
}
|
||||
|
||||
fn targetFunction(x: i32) usize {
|
||||
assert(x == 1234);
|
||||
|
||||
var local_variable: i32 = 42;
|
||||
const ptr = &local_variable;
|
||||
ptr.* += 1;
|
||||
|
||||
assert(local_variable == 43);
|
||||
return @ptrToInt(ptr);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@OpaqueType#}
|
||||
<pre>{#syntax#}@OpaqueType() type{#endsyntax#}</pre>
|
||||
<p>
|
||||
|
@ -184,7 +184,7 @@ fn posixCallMainAndExit() noreturn {
|
||||
// 0,
|
||||
//) catch @panic("out of memory");
|
||||
//std.os.mprotect(new_stack[0..std.mem.page_size], std.os.PROT_NONE) catch {};
|
||||
//std.os.exit(@newStackCall(new_stack, callMainWithArgs, argc, argv, envp));
|
||||
//std.os.exit(@call(.{.stack = new_stack}, callMainWithArgs, .{argc, argv, envp}));
|
||||
}
|
||||
|
||||
std.os.exit(@call(.{ .modifier = .always_inline }, callMainWithArgs, .{ argc, argv, envp }));
|
||||
|
@ -321,7 +321,7 @@ pub const Inst = struct {
|
||||
}
|
||||
|
||||
const llvm_cc = llvm.CCallConv;
|
||||
const fn_inline = llvm.FnInline.Auto;
|
||||
const call_attr = llvm.CallAttr.Auto;
|
||||
|
||||
return llvm.BuildCall(
|
||||
ofile.builder,
|
||||
@ -329,7 +329,7 @@ pub const Inst = struct {
|
||||
args.ptr,
|
||||
@intCast(c_uint, args.len),
|
||||
llvm_cc,
|
||||
fn_inline,
|
||||
call_attr,
|
||||
"",
|
||||
) orelse error.OutOfMemory;
|
||||
}
|
||||
|
25
src/ir.cpp
25
src/ir.cpp
@ -13358,6 +13358,15 @@ static IrInstruction *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst
|
||||
return ir_get_deref(ira, source_instr, field_ptr, nullptr);
|
||||
}
|
||||
|
||||
static IrInstruction *ir_analyze_optional_value_payload_value(IrAnalyze *ira, IrInstruction *source_instr,
|
||||
IrInstruction *optional_operand, bool safety_check_on)
|
||||
{
|
||||
IrInstruction *opt_ptr = ir_get_ref(ira, source_instr, optional_operand, true, false);
|
||||
IrInstruction *payload_ptr = ir_analyze_unwrap_optional_payload(ira, source_instr, opt_ptr,
|
||||
safety_check_on, false);
|
||||
return ir_get_deref(ira, source_instr, payload_ptr, nullptr);
|
||||
}
|
||||
|
||||
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
|
||||
ZigType *wanted_type, IrInstruction *value)
|
||||
{
|
||||
@ -17521,7 +17530,7 @@ static IrInstruction *analyze_casted_new_stack(IrAnalyze *ira, IrInstruction *so
|
||||
arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr)
|
||||
{
|
||||
ir_add_error(ira, source_instr,
|
||||
buf_sprintf("target arch '%s' does not support @newStackCall",
|
||||
buf_sprintf("target arch '%s' does not support calling with a new stack",
|
||||
target_arch_name(ira->codegen->zig_target->arch)));
|
||||
}
|
||||
|
||||
@ -18223,13 +18232,21 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc
|
||||
|
||||
TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack"));
|
||||
ir_assert(stack_field != nullptr, source_instr);
|
||||
IrInstruction *stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field);
|
||||
IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, stack);
|
||||
IrInstruction *opt_stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field);
|
||||
if (type_is_invalid(opt_stack->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, opt_stack);
|
||||
bool stack_is_non_null;
|
||||
if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null))
|
||||
return ira->codegen->invalid_instruction;
|
||||
if (!stack_is_non_null)
|
||||
IrInstruction *stack;
|
||||
if (stack_is_non_null) {
|
||||
stack = ir_analyze_optional_value_payload_value(ira, source_instr, opt_stack, false);
|
||||
if (type_is_invalid(stack->value->type))
|
||||
return ira->codegen->invalid_instruction;
|
||||
} else {
|
||||
stack = nullptr;
|
||||
}
|
||||
|
||||
return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr,
|
||||
modifier, stack, false, args_ptr, args_len, nullptr, result_loc);
|
||||
|
@ -26,8 +26,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\fn baz2() void {}
|
||||
,
|
||||
"tmp.zig:2:21: error: expected tuple or struct, found 'void'",
|
||||
"tmp.zig:5:58: error: unable to perform 'never_inline' call at compile-time",
|
||||
"tmp.zig:8:56: error: unable to perform 'never_tail' call at compile-time",
|
||||
"tmp.zig:5:14: error: unable to perform 'never_inline' call at compile-time",
|
||||
"tmp.zig:8:14: error: unable to perform 'never_tail' call at compile-time",
|
||||
"tmp.zig:11:5: error: no-inline call of inline function",
|
||||
"tmp.zig:15:43: error: unable to evaluate constant expression",
|
||||
);
|
||||
@ -44,13 +44,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
);
|
||||
|
||||
cases.addCase(x: {
|
||||
var tc = cases.create("@newStackCall on unsupported target",
|
||||
var tc = cases.create("call with new stack on unsupported target",
|
||||
\\export fn entry() void {
|
||||
\\ var buf: [10]u8 align(16) = undefined;
|
||||
\\ @newStackCall(&buf, foo);
|
||||
\\ @call(.{.stack = &buf}, foo);
|
||||
\\}
|
||||
\\fn foo() void {}
|
||||
, "tmp.zig:3:5: error: target arch 'wasm32' does not support @newStackCall");
|
||||
, "tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack");
|
||||
tc.target = tests.Target{
|
||||
.Cross = tests.CrossTarget{
|
||||
.arch = .wasm32,
|
||||
|
@ -18,8 +18,8 @@ test "calling a function with a new stack" {
|
||||
|
||||
const arg = 1234;
|
||||
|
||||
const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
|
||||
const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
|
||||
const a = @call(.{ .stack = new_stack_bytes[0..512] }, targetFunction, .{arg});
|
||||
const b = @call(.{ .stack = new_stack_bytes[512..] }, targetFunction, .{arg});
|
||||
_ = targetFunction(arg);
|
||||
|
||||
expect(arg == 1234);
|
||||
|
Loading…
x
Reference in New Issue
Block a user