mem: implicit-Context platform fixes — chess green on macOS/iOS/Android
Verify-step uncovered three categories of regressions where sx code
calls into the platform's C ABI through fn-pointer types or as a
registered callback. Every site now declares the right convention.
C-side calls INTO sx → callconv(.c) on the sx function:
- platform/android.sx: sx_android_render_thread_entry is the start
routine pthread_create invokes — pthread treats it as a C function.
Also annotate the pthread_create signature so the start-routine fn-
pointer field rejects mismatching sx fns at compile time.
sx code calling typed fn-pointers cast from C symbols → callconv(.c)
on the fn-pointer type:
- opengl.sx: 55 GL fn-ptr globals + load_gl's proc-loader param. GL
trampolines are macOS/iOS/Android system code.
- std/objc.sx: the two typed `objc_msgSend` casts.
- gpu/metal.sx: ~40 typed `objc_msgSend` casts across Metal command
encoder / device / pipeline construction.
The block invoke trampolines (objc_block.sx) call back INTO sx (the
closure trampoline). The typed fn-ptr there stays default-conv so
ctx prepends correctly. Compiler change: a callconv(.c) sx function
now binds `current_ctx_ref` to `&__sx_default_context` at entry (used
to be gated by `isExportedEntryName`). C-callable sx callbacks like
the block invokes don't get their own __sx_ctx param but their bodies
still need a real Context to forward to the closure they delegate to.
Tests: 152/152 example suite + chess green on all 3 platforms.
Screenshots at /tmp/sx-game-{macos,iossim,android}.png.
This commit is contained in:
@@ -250,11 +250,11 @@ metal_init_ios :: (self: *MetalGPU) -> bool {
|
||||
if self.device == null { return false; }
|
||||
}
|
||||
|
||||
msg_oo : (*void, *void, *void) -> void = xx objc_msgSend;
|
||||
msg_ou : (*void, *void, u64) -> void = xx objc_msgSend;
|
||||
msg_ob : (*void, *void, u8) -> void = xx objc_msgSend;
|
||||
msg_osize : (*void, *void, CGSize) -> void = xx objc_msgSend;
|
||||
msg_o : (*void, *void) -> *void = xx objc_msgSend;
|
||||
msg_oo : (*void, *void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_ou : (*void, *void, u64) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_ob : (*void, *void, u8) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_osize : (*void, *void, CGSize) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_o : (*void, *void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
|
||||
if self.queue == null {
|
||||
self.queue = msg_o(self.device, sel_registerName("newCommandQueue".ptr));
|
||||
@@ -283,7 +283,7 @@ metal_resize_ios :: (self: *MetalGPU) {
|
||||
inline if OS != .ios { return; }
|
||||
if self.layer == null { return; }
|
||||
|
||||
msg_osize : (*void, *void, CGSize) -> void = xx objc_msgSend;
|
||||
msg_osize : (*void, *void, CGSize) -> void callconv(.c) = xx objc_msgSend;
|
||||
size := CGSize.{ width = xx self.pixel_w, height = xx self.pixel_h };
|
||||
msg_osize(self.layer, sel_registerName("setDrawableSize:".ptr), size);
|
||||
}
|
||||
@@ -294,12 +294,12 @@ metal_begin_frame_ios :: (self: *MetalGPU, clear: ClearColor) -> bool {
|
||||
if self.queue == null { return false; }
|
||||
if self.pixel_w <= 0 or self.pixel_h <= 0 { return false; }
|
||||
|
||||
msg_o : (*void, *void) -> *void = xx objc_msgSend;
|
||||
msg_oo : (*void, *void, *void) -> void = xx objc_msgSend;
|
||||
msg_oo_ret : (*void, *void, *void) -> *void = xx objc_msgSend;
|
||||
msg_ou : (*void, *void, u64) -> void = xx objc_msgSend;
|
||||
msg_ouret : (*void, *void, u64) -> *void = xx objc_msgSend;
|
||||
msg_oclear : (*void, *void, MTLClearColor) -> void = xx objc_msgSend;
|
||||
msg_o : (*void, *void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
msg_oo : (*void, *void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_oo_ret : (*void, *void, *void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
msg_ou : (*void, *void, u64) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_ouret : (*void, *void, u64) -> *void callconv(.c) = xx objc_msgSend;
|
||||
msg_oclear : (*void, *void, MTLClearColor) -> void callconv(.c) = xx objc_msgSend;
|
||||
|
||||
// drawable = [layer nextDrawable]
|
||||
self.drawable = msg_o(self.layer, sel_registerName("nextDrawable".ptr));
|
||||
@@ -346,9 +346,9 @@ metal_end_frame_ios :: (self: *MetalGPU, target_time: f64) {
|
||||
if self.cmd_buffer == null { return; }
|
||||
if self.drawable == null { return; }
|
||||
|
||||
msg_v : (*void, *void) -> void = xx objc_msgSend;
|
||||
msg_oo : (*void, *void, *void) -> void = xx objc_msgSend;
|
||||
msg_ood : (*void, *void, *void, f64) -> void = xx objc_msgSend;
|
||||
msg_v : (*void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_oo : (*void, *void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_ood : (*void, *void, *void, f64) -> void callconv(.c) = xx objc_msgSend;
|
||||
|
||||
msg_v(self.encoder, sel_registerName("endEncoding".ptr));
|
||||
|
||||
@@ -379,15 +379,15 @@ metal_create_shader_ios :: (self: *MetalGPU, src: string) -> u32 {
|
||||
inline if OS != .ios { return 0; }
|
||||
if self.device == null { return 0; }
|
||||
|
||||
msg_o : (*void, *void) -> *void = xx objc_msgSend;
|
||||
msg_oo : (*void, *void, *void) -> void = xx objc_msgSend;
|
||||
msg_oo_r : (*void, *void, *void) -> *void = xx objc_msgSend;
|
||||
msg_ou : (*void, *void, u64) -> void = xx objc_msgSend;
|
||||
msg_ouret: (*void, *void, u64) -> *void = xx objc_msgSend;
|
||||
msg_ob : (*void, *void, u8) -> void = xx objc_msgSend;
|
||||
msg_o : (*void, *void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
msg_oo : (*void, *void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_oo_r : (*void, *void, *void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
msg_ou : (*void, *void, u64) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_ouret: (*void, *void, u64) -> *void callconv(.c) = xx objc_msgSend;
|
||||
msg_ob : (*void, *void, u8) -> void callconv(.c) = xx objc_msgSend;
|
||||
|
||||
// [device newLibraryWithSource:src options:nil error:&err]
|
||||
msg_lib : (*void, *void, *void, *void, **void) -> *void = xx objc_msgSend;
|
||||
msg_lib : (*void, *void, *void, *void, **void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
src_ns := ns_string(src.ptr);
|
||||
err : *void = null;
|
||||
library := msg_lib(self.device,
|
||||
@@ -422,7 +422,7 @@ metal_create_shader_ios :: (self: *MetalGPU, src: string) -> u32 {
|
||||
msg_ou(att0, sel_registerName("setSourceAlphaBlendFactor:".ptr), MTL_BLEND_FACTOR_SRC_ALPHA);
|
||||
msg_ou(att0, sel_registerName("setDestinationAlphaBlendFactor:".ptr), MTL_BLEND_FACTOR_ONE_MINUS_SRC_A);
|
||||
|
||||
msg_pipe : (*void, *void, *void, **void) -> *void = xx objc_msgSend;
|
||||
msg_pipe : (*void, *void, *void, **void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
err2 : *void = null;
|
||||
state := msg_pipe(self.device,
|
||||
sel_registerName("newRenderPipelineStateWithDescriptor:error:".ptr),
|
||||
@@ -446,7 +446,7 @@ metal_create_buffer_ios :: (self: *MetalGPU, size_bytes: s64) -> u32 {
|
||||
if size_bytes <= 0 { return 0; }
|
||||
|
||||
// MTLResourceStorageModeShared is the default (option value 0).
|
||||
msg_buf : (*void, *void, u64, u64) -> *void = xx objc_msgSend;
|
||||
msg_buf : (*void, *void, u64, u64) -> *void callconv(.c) = xx objc_msgSend;
|
||||
buf := msg_buf(self.device,
|
||||
sel_registerName("newBufferWithLength:options:".ptr),
|
||||
xx size_bytes, 0);
|
||||
@@ -463,7 +463,7 @@ metal_update_buffer_ios :: (self: *MetalGPU, handle: u32, data: *void, size_byte
|
||||
if data == null { return; }
|
||||
if size_bytes <= 0 { return; }
|
||||
|
||||
msg_o : (*void, *void) -> *void = xx objc_msgSend;
|
||||
msg_o : (*void, *void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
dst := msg_o(buf, sel_registerName("contents".ptr));
|
||||
if dst == null { return; }
|
||||
memcpy(dst, data, size_bytes);
|
||||
@@ -477,7 +477,7 @@ metal_update_buffer_at_ios :: (self: *MetalGPU, handle: u32, data: *void, size_b
|
||||
if size_bytes <= 0 { return; }
|
||||
if byte_offset < 0 { return; }
|
||||
|
||||
msg_o : (*void, *void) -> *void = xx objc_msgSend;
|
||||
msg_o : (*void, *void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
base := msg_o(buf, sel_registerName("contents".ptr));
|
||||
if base == null { return; }
|
||||
// Add byte_offset via integer arithmetic — `@dst[i]` on `[*]u8`
|
||||
@@ -524,7 +524,7 @@ metal_create_texture_ios :: (self: *MetalGPU, w: s32, h: s32, format: TextureFor
|
||||
|
||||
// [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:width:height:mipmapped:]
|
||||
MTLTextureDescriptor := objc_getClass("MTLTextureDescriptor".ptr);
|
||||
msg_desc : (*void, *void, u64, u64, u64, u8) -> *void = xx objc_msgSend;
|
||||
msg_desc : (*void, *void, u64, u64, u64, u8) -> *void callconv(.c) = xx objc_msgSend;
|
||||
desc := msg_desc(MTLTextureDescriptor,
|
||||
sel_registerName("texture2DDescriptorWithPixelFormat:width:height:mipmapped:".ptr),
|
||||
pixel_format, xx w, xx h, 0);
|
||||
@@ -533,10 +533,10 @@ metal_create_texture_ios :: (self: *MetalGPU, w: s32, h: s32, format: TextureFor
|
||||
// Force shared storage so the CPU can keep writing pixels (atlas updates,
|
||||
// sprite uploads). On iOS-sim under Apple Silicon the convenience class
|
||||
// method's default storage isn't reliably shared for every format.
|
||||
msg_ou_void : (*void, *void, u64) -> void = xx objc_msgSend;
|
||||
msg_ou_void : (*void, *void, u64) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg_ou_void(desc, sel_registerName("setStorageMode:".ptr), MTL_STORAGE_MODE_SHARED);
|
||||
|
||||
msg_oo : (*void, *void, *void) -> *void = xx objc_msgSend;
|
||||
msg_oo : (*void, *void, *void) -> *void callconv(.c) = xx objc_msgSend;
|
||||
tex := msg_oo(self.device, sel_registerName("newTextureWithDescriptor:".ptr), desc);
|
||||
if tex == null { return 0; }
|
||||
|
||||
@@ -590,7 +590,7 @@ metal_destroy_shader_ios :: (self: *MetalGPU, handle: u32) {
|
||||
if h64 > self.shaders.len { return; }
|
||||
obj := self.shaders.items[handle - 1];
|
||||
if obj == null { return; }
|
||||
msg : (*void, *void) -> void = xx objc_msgSend;
|
||||
msg : (*void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg(obj, sel_registerName("release".ptr));
|
||||
self.shaders.items[handle - 1] = null;
|
||||
}
|
||||
@@ -602,7 +602,7 @@ metal_destroy_buffer_ios :: (self: *MetalGPU, handle: u32) {
|
||||
if h64 > self.buffers.len { return; }
|
||||
obj := self.buffers.items[handle - 1];
|
||||
if obj == null { return; }
|
||||
msg : (*void, *void) -> void = xx objc_msgSend;
|
||||
msg : (*void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg(obj, sel_registerName("release".ptr));
|
||||
self.buffers.items[handle - 1] = null;
|
||||
}
|
||||
@@ -614,7 +614,7 @@ metal_destroy_texture_ios :: (self: *MetalGPU, handle: u32) {
|
||||
if h64 > self.textures.len { return; }
|
||||
obj := self.textures.items[handle - 1].tex;
|
||||
if obj == null { return; }
|
||||
msg : (*void, *void) -> void = xx objc_msgSend;
|
||||
msg : (*void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg(obj, sel_registerName("release".ptr));
|
||||
self.textures.items[handle - 1].tex = null;
|
||||
self.textures.items[handle - 1].bytes_per_pixel = 0;
|
||||
@@ -627,7 +627,7 @@ metal_set_shader_ios :: (self: *MetalGPU, sh: u32) {
|
||||
if self.encoder == null { return; }
|
||||
state := metal_lookup_shader(self, sh);
|
||||
if state == null { return; }
|
||||
msg : (*void, *void, *void) -> void = xx objc_msgSend;
|
||||
msg : (*void, *void, *void) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg(self.encoder, sel_registerName("setRenderPipelineState:".ptr), state);
|
||||
}
|
||||
|
||||
@@ -637,7 +637,7 @@ metal_set_vertex_buffer_ios :: (self: *MetalGPU, h: u32) {
|
||||
buf := metal_lookup_buffer(self, h);
|
||||
if buf == null { return; }
|
||||
// [encoder setVertexBuffer:buf offset:0 atIndex:0]
|
||||
msg : (*void, *void, *void, u64, u64) -> void = xx objc_msgSend;
|
||||
msg : (*void, *void, *void, u64, u64) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg(self.encoder, sel_registerName("setVertexBuffer:offset:atIndex:".ptr), buf, 0, 0);
|
||||
}
|
||||
|
||||
@@ -650,7 +650,7 @@ metal_set_texture_ios :: (self: *MetalGPU, slot: u32, h: u32) {
|
||||
tex := self.textures.items[h - 1].tex;
|
||||
if tex == null { return; }
|
||||
// [encoder setFragmentTexture:tex atIndex:slot]
|
||||
msg : (*void, *void, *void, u64) -> void = xx objc_msgSend;
|
||||
msg : (*void, *void, *void, u64) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg(self.encoder, sel_registerName("setFragmentTexture:atIndex:".ptr), tex, xx slot);
|
||||
}
|
||||
|
||||
@@ -660,7 +660,7 @@ metal_set_vertex_constants_ios :: (self: *MetalGPU, slot: u32, data: *void, size
|
||||
if data == null { return; }
|
||||
if size_bytes <= 0 { return; }
|
||||
// [encoder setVertexBytes:data length:size_bytes atIndex:slot]
|
||||
msg : (*void, *void, *void, u64, u64) -> void = xx objc_msgSend;
|
||||
msg : (*void, *void, *void, u64, u64) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg(self.encoder, sel_registerName("setVertexBytes:length:atIndex:".ptr),
|
||||
data, xx size_bytes, xx slot);
|
||||
}
|
||||
@@ -689,7 +689,7 @@ metal_draw_triangles_ios :: (self: *MetalGPU, vertex_offset: s32, vertex_count:
|
||||
if self.encoder == null { return; }
|
||||
if vertex_count <= 0 { return; }
|
||||
// [encoder drawPrimitives:.triangle vertexStart:offset vertexCount:count]
|
||||
msg : (*void, *void, u64, u64, u64) -> void = xx objc_msgSend;
|
||||
msg : (*void, *void, u64, u64, u64) -> void callconv(.c) = xx objc_msgSend;
|
||||
msg(self.encoder, sel_registerName("drawPrimitives:vertexStart:vertexCount:".ptr),
|
||||
MTL_PRIMITIVE_TYPE_TRIANGLE, xx vertex_offset, xx vertex_count);
|
||||
}
|
||||
|
||||
@@ -25,39 +25,39 @@ GL_LINE :u32: 0x1B01;
|
||||
GL_FILL :u32: 0x1B02;
|
||||
|
||||
// Function pointer variables (mutable, loaded at runtime)
|
||||
glClearColor : (f32, f32, f32, f32) -> void = ---;
|
||||
glClear : (u32) -> void = ---;
|
||||
glEnable : (u32) -> void = ---;
|
||||
glDisable : (u32) -> void = ---;
|
||||
glViewport : (s32, s32, s32, s32) -> void = ---;
|
||||
glFlush : () -> void = ---;
|
||||
glDrawArrays : (u32, s32, s32) -> void = ---;
|
||||
glPolygonMode : (u32, u32) -> void = ---;
|
||||
glLineWidth : (f32) -> void = ---;
|
||||
glCreateShader : (u32) -> u32 = ---;
|
||||
glShaderSource : (u32, s32, *[:0]u8, *s32) -> void = ---;
|
||||
glCompileShader : (u32) -> void = ---;
|
||||
glGetShaderiv : (u32, u32, *s32) -> void = ---;
|
||||
glGetShaderInfoLog : (u32, s32, *s32, [*]u8) -> void = ---;
|
||||
glCreateProgram : () -> u32 = ---;
|
||||
glAttachShader : (u32, u32) -> void = ---;
|
||||
glLinkProgram : (u32) -> void = ---;
|
||||
glGetProgramiv : (u32, u32, *s32) -> void = ---;
|
||||
glGetProgramInfoLog : (u32, s32, *s32, [*]u8) -> void = ---;
|
||||
glUseProgram : (u32) -> void = ---;
|
||||
glDeleteShader : (u32) -> void = ---;
|
||||
glGenVertexArrays : (s32, *u32) -> void = ---;
|
||||
glGenBuffers : (s32, *u32) -> void = ---;
|
||||
glBindVertexArray : (u32) -> void = ---;
|
||||
glBindBuffer : (u32, u32) -> void = ---;
|
||||
glBufferData : (u32, isize, *void, u32) -> void = ---;
|
||||
glVertexAttribPointer : (u32, s32, u32, u8, s32, *void) -> void = ---;
|
||||
glEnableVertexAttribArray : (u32) -> void = ---;
|
||||
glGetUniformLocation : (u32, [*]u8) -> s32 = ---;
|
||||
glUniformMatrix4fv : (s32, s32, u8, [*]f32) -> void = ---;
|
||||
glUniform3f : (s32, f32, f32, f32) -> void = ---;
|
||||
glDepthFunc : (u32) -> void = ---;
|
||||
glUniform1f : (s32, f32) -> void = ---;
|
||||
glClearColor : (f32, f32, f32, f32) -> void callconv(.c) = ---;
|
||||
glClear : (u32) -> void callconv(.c) = ---;
|
||||
glEnable : (u32) -> void callconv(.c) = ---;
|
||||
glDisable : (u32) -> void callconv(.c) = ---;
|
||||
glViewport : (s32, s32, s32, s32) -> void callconv(.c) = ---;
|
||||
glFlush : () -> void callconv(.c) = ---;
|
||||
glDrawArrays : (u32, s32, s32) -> void callconv(.c) = ---;
|
||||
glPolygonMode : (u32, u32) -> void callconv(.c) = ---;
|
||||
glLineWidth : (f32) -> void callconv(.c) = ---;
|
||||
glCreateShader : (u32) -> u32 callconv(.c) = ---;
|
||||
glShaderSource : (u32, s32, *[:0]u8, *s32) -> void callconv(.c) = ---;
|
||||
glCompileShader : (u32) -> void callconv(.c) = ---;
|
||||
glGetShaderiv : (u32, u32, *s32) -> void callconv(.c) = ---;
|
||||
glGetShaderInfoLog : (u32, s32, *s32, [*]u8) -> void callconv(.c) = ---;
|
||||
glCreateProgram : () -> u32 callconv(.c) = ---;
|
||||
glAttachShader : (u32, u32) -> void callconv(.c) = ---;
|
||||
glLinkProgram : (u32) -> void callconv(.c) = ---;
|
||||
glGetProgramiv : (u32, u32, *s32) -> void callconv(.c) = ---;
|
||||
glGetProgramInfoLog : (u32, s32, *s32, [*]u8) -> void callconv(.c) = ---;
|
||||
glUseProgram : (u32) -> void callconv(.c) = ---;
|
||||
glDeleteShader : (u32) -> void callconv(.c) = ---;
|
||||
glGenVertexArrays : (s32, *u32) -> void callconv(.c) = ---;
|
||||
glGenBuffers : (s32, *u32) -> void callconv(.c) = ---;
|
||||
glBindVertexArray : (u32) -> void callconv(.c) = ---;
|
||||
glBindBuffer : (u32, u32) -> void callconv(.c) = ---;
|
||||
glBufferData : (u32, isize, *void, u32) -> void callconv(.c) = ---;
|
||||
glVertexAttribPointer : (u32, s32, u32, u8, s32, *void) -> void callconv(.c) = ---;
|
||||
glEnableVertexAttribArray : (u32) -> void callconv(.c) = ---;
|
||||
glGetUniformLocation : (u32, [*]u8) -> s32 callconv(.c) = ---;
|
||||
glUniformMatrix4fv : (s32, s32, u8, [*]f32) -> void callconv(.c) = ---;
|
||||
glUniform3f : (s32, f32, f32, f32) -> void callconv(.c) = ---;
|
||||
glDepthFunc : (u32) -> void callconv(.c) = ---;
|
||||
glUniform1f : (s32, f32) -> void callconv(.c) = ---;
|
||||
GL_LESS :u32: 0x0201;
|
||||
GL_LEQUAL :u32: 0x0203;
|
||||
GL_SCISSOR_TEST :u32: 0x0C11;
|
||||
@@ -76,27 +76,27 @@ GL_RED :u32: 0x1903;
|
||||
GL_R8 :u32: 0x8229;
|
||||
GL_UNPACK_ALIGNMENT :u32: 0x0CF5;
|
||||
|
||||
glScissor : (s32, s32, s32, s32) -> void = ---;
|
||||
glBufferSubData : (u32, isize, isize, *void) -> void = ---;
|
||||
glGenTextures : (s32, *u32) -> void = ---;
|
||||
glBindTexture : (u32, u32) -> void = ---;
|
||||
glTexImage2D : (u32, s32, s32, s32, s32, s32, u32, u32, *void) -> void = ---;
|
||||
glTexParameteri : (u32, u32, s32) -> void = ---;
|
||||
glBlendFunc : (u32, u32) -> void = ---;
|
||||
glReadPixels : (s32, s32, s32, s32, u32, u32, *void) -> void = ---;
|
||||
glActiveTexture : (u32) -> void = ---;
|
||||
glUniform1i : (s32, s32) -> void = ---;
|
||||
glPixelStorei : (u32, s32) -> void = ---;
|
||||
glTexSubImage2D : (u32, s32, s32, s32, s32, s32, u32, u32, *void) -> void = ---;
|
||||
glDeleteTextures : (s32, *u32) -> void = ---;
|
||||
glScissor : (s32, s32, s32, s32) -> void callconv(.c) = ---;
|
||||
glBufferSubData : (u32, isize, isize, *void) -> void callconv(.c) = ---;
|
||||
glGenTextures : (s32, *u32) -> void callconv(.c) = ---;
|
||||
glBindTexture : (u32, u32) -> void callconv(.c) = ---;
|
||||
glTexImage2D : (u32, s32, s32, s32, s32, s32, u32, u32, *void) -> void callconv(.c) = ---;
|
||||
glTexParameteri : (u32, u32, s32) -> void callconv(.c) = ---;
|
||||
glBlendFunc : (u32, u32) -> void callconv(.c) = ---;
|
||||
glReadPixels : (s32, s32, s32, s32, u32, u32, *void) -> void callconv(.c) = ---;
|
||||
glActiveTexture : (u32) -> void callconv(.c) = ---;
|
||||
glUniform1i : (s32, s32) -> void callconv(.c) = ---;
|
||||
glPixelStorei : (u32, s32) -> void callconv(.c) = ---;
|
||||
glTexSubImage2D : (u32, s32, s32, s32, s32, s32, u32, u32, *void) -> void callconv(.c) = ---;
|
||||
glDeleteTextures : (s32, *u32) -> void callconv(.c) = ---;
|
||||
|
||||
glGenFramebuffers : (s32, *u32) -> void = ---;
|
||||
glGenRenderbuffers : (s32, *u32) -> void = ---;
|
||||
glBindFramebuffer : (u32, u32) -> void = ---;
|
||||
glBindRenderbuffer : (u32, u32) -> void = ---;
|
||||
glFramebufferRenderbuffer : (u32, u32, u32, u32) -> void = ---;
|
||||
glGetRenderbufferParameteriv : (u32, u32, *s32) -> void = ---;
|
||||
glCheckFramebufferStatus : (u32) -> u32 = ---;
|
||||
glGenFramebuffers : (s32, *u32) -> void callconv(.c) = ---;
|
||||
glGenRenderbuffers : (s32, *u32) -> void callconv(.c) = ---;
|
||||
glBindFramebuffer : (u32, u32) -> void callconv(.c) = ---;
|
||||
glBindRenderbuffer : (u32, u32) -> void callconv(.c) = ---;
|
||||
glFramebufferRenderbuffer : (u32, u32, u32, u32) -> void callconv(.c) = ---;
|
||||
glGetRenderbufferParameteriv : (u32, u32, *s32) -> void callconv(.c) = ---;
|
||||
glCheckFramebufferStatus : (u32) -> u32 callconv(.c) = ---;
|
||||
|
||||
GL_TEXTURE_WRAP_S :u32: 0x2802;
|
||||
GL_TEXTURE_WRAP_T :u32: 0x2803;
|
||||
@@ -104,7 +104,7 @@ GL_CLAMP_TO_EDGE :u32: 0x812F;
|
||||
|
||||
// Loader: call once after creating GL context
|
||||
// Pass in a proc loader (e.g. SDL_GL_GetProcAddress)
|
||||
load_gl :: (get_proc: ([*]u8) -> *void) {
|
||||
load_gl :: (get_proc: ([*]u8) -> *void callconv(.c)) {
|
||||
glClearColor = xx get_proc("glClearColor");
|
||||
glClear = xx get_proc("glClear");
|
||||
glEnable = xx get_proc("glEnable");
|
||||
|
||||
@@ -85,7 +85,7 @@ ANativeWindow_setBuffersGeometry :: (w: *void, width: s32, height: s32, fmt: s32
|
||||
AAssetManager_fromJava :: (env: *void, mgr: *void) -> *void #foreign;
|
||||
|
||||
// pthread (link libpthread is built into bionic).
|
||||
pthread_create :: (thread: *u64, attr: *void, start: (*void) -> *void, arg: *void) -> s32 #foreign;
|
||||
pthread_create :: (thread: *u64, attr: *void, start: (*void) -> *void callconv(.c), arg: *void) -> s32 #foreign;
|
||||
pthread_mutex_init :: (m: *void, attr: *void) -> s32 #foreign;
|
||||
pthread_mutex_lock :: (m: *void) -> s32 #foreign;
|
||||
pthread_mutex_unlock :: (m: *void) -> s32 #foreign;
|
||||
@@ -254,7 +254,7 @@ sx_android_start_render_thread :: (plat: *AndroidPlatform, entry_fn: () -> void)
|
||||
plat.render_thread_started = true;
|
||||
}
|
||||
|
||||
sx_android_render_thread_entry :: (arg: *void) -> *void {
|
||||
sx_android_render_thread_entry :: (arg: *void) -> *void callconv(.c) {
|
||||
plat : *AndroidPlatform = xx arg;
|
||||
while plat.app_window == null and !plat.should_stop {
|
||||
usleep(1000);
|
||||
|
||||
@@ -62,7 +62,7 @@ NSLog :: (fmt: *void) #foreign;
|
||||
ns_string :: (s: [*]u8) -> *void {
|
||||
cls := objc_getClass("NSString".ptr);
|
||||
sel := sel_registerName("stringWithUTF8String:".ptr);
|
||||
fn_ptr : (*void, *void, [*]u8) -> *void = xx objc_msgSend;
|
||||
fn_ptr : (*void, *void, [*]u8) -> *void callconv(.c) = xx objc_msgSend;
|
||||
return fn_ptr(cls, sel, s);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,6 @@ ns_string :: (s: [*]u8) -> *void {
|
||||
// tied to the NSString; don't free it.
|
||||
c_string :: (ns: *void) -> [*]u8 {
|
||||
sel := sel_registerName("UTF8String".ptr);
|
||||
fn_ptr : (*void, *void) -> [*]u8 = xx objc_msgSend;
|
||||
fn_ptr : (*void, *void) -> [*]u8 callconv(.c) = xx objc_msgSend;
|
||||
return fn_ptr(ns, sel);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,10 @@ __sx_block_descriptor : BlockDescriptor = .{
|
||||
// Signature: `void (^)(void)` — no args, no return. The single most
|
||||
// common Apple block shape (UIView animation bodies, dispatch_async, etc).
|
||||
__block_invoke_void :: (block_self: *Block) callconv(.c) {
|
||||
// `sx_fn` is the closure trampoline — an sx-side function with the
|
||||
// implicit __sx_ctx at slot 0 and env at slot 1. We're a callconv(.c)
|
||||
// entry, so the call site needs ctx prepended; the typed fn-pointer
|
||||
// type stays default-conv to enable that.
|
||||
typed_fn : (*void) -> void = xx block_self.sx_fn;
|
||||
typed_fn(block_self.sx_env);
|
||||
}
|
||||
|
||||
@@ -1006,9 +1006,12 @@ pub const Lowering = struct {
|
||||
scope.put(p.name, .{ .ref = slot, .ty = pty, .is_alloca = true });
|
||||
}
|
||||
|
||||
// Inbound entry points: bind current_ctx_ref to the static default
|
||||
// before any user code runs.
|
||||
if (!wants_ctx and self.implicit_ctx_enabled and isExportedEntryName(name)) {
|
||||
// Inbound entry points and callconv(.c) sx functions: bind
|
||||
// current_ctx_ref to the static default before any user code
|
||||
// runs. C-callable sx functions don't get a __sx_ctx param,
|
||||
// but their bodies may call ctx-aware sx functions / fn-ptrs
|
||||
// and need a real Context to forward.
|
||||
if (!wants_ctx and self.implicit_ctx_enabled) {
|
||||
if (self.global_names.get("__sx_default_context")) |dctx_gi| {
|
||||
self.current_ctx_ref = self.builder.emit(.{ .global_addr = dctx_gi.id }, self.module.types.ptrTo(.void));
|
||||
}
|
||||
@@ -1147,8 +1150,10 @@ pub const Lowering = struct {
|
||||
scope.put(p.name, .{ .ref = slot, .ty = pty, .is_alloca = true });
|
||||
}
|
||||
|
||||
// Inbound entry points: bind current_ctx_ref to &__sx_default_context.
|
||||
if (!wants_ctx_lf and self.implicit_ctx_enabled and isExportedEntryName(name)) {
|
||||
// Inbound entry points + callconv(.c) sx functions: bind
|
||||
// current_ctx_ref to &__sx_default_context. See companion comment
|
||||
// in `lowerFunction` for the same case.
|
||||
if (!wants_ctx_lf and self.implicit_ctx_enabled) {
|
||||
if (self.global_names.get("__sx_default_context")) |dctx_gi| {
|
||||
self.current_ctx_ref = self.builder.emit(.{ .global_addr = dctx_gi.id }, self.module.types.ptrTo(.void));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user