mem: Step 3 — thread __sx_ctx through closure/fn-pointer/method dispatch

Continues the implicit-Context refactor. Bare-fn trampolines, lambda
trampolines, and protocol thunks now carry __sx_ctx at slot 0; call
sites for closures, fn-pointer variables, and method dispatch prepend
the caller's current ctx.

- emit_llvm.zig:1687 call_indirect treats `fp_ctx_slots` leading args
  as opaque ptr (the implicit ctx) when the fn-pointer is default-conv
  under has_implicit_ctx.
- lower.zig:fnPtrTypeWantsCtx predicate gates the prepend at both
  scope-local and global fn-pointer call sites.
- lower.zig:fixupMethodReceiver skips __sx_ctx when probing the
  receiver param's type.
- lower.zig:lowerLambda builds closure type from user-visible params
  only (skip ctx + env).
- lower.zig:closure(bare_fn) builds closure type from user-visible
  params only.
- module.zig: Module.has_implicit_ctx flag mirrors Lowering's switch
  so emit_llvm can read it without a back-pointer.

Tests updated:
- 5 ObjC-block/runtime tests get `callconv(.c)` on fn-ptr types
  cast from `objc_msgSend` / Block.invoke (C-side calls into sx).
- ffi-06-callback gets `callconv(.c)` on double_it/add_with_ctx —
  the registered C-side callbacks.
- 08-types snapshot regen (undefined-init drift from layout shift).
- 11 JNI/ObjC .ir snapshots regen for the ctx-prepended thunk
  signatures.

151/152 example tests pass. Remaining failure (05-run) is the
comptime/interp path that requires Step 7 (callWithDefaultContext).
This commit is contained in:
agra
2026-05-25 08:41:50 +03:00
parent 29784c22a8
commit 92c6b47f12
22 changed files with 1601 additions and 1196 deletions

View File

@@ -18,10 +18,10 @@ main :: () -> s32 {
sel_with_utf8 := sel_registerName("stringWithUTF8String:".ptr);
sel_utf8 := sel_registerName("UTF8String".ptr);
msg_3 : (*void, *void, [*]u8) -> *void = xx objc_msgSend;
msg_3 : (*void, *void, [*]u8) -> *void callconv(.c) = xx objc_msgSend;
ns_str := msg_3(ns_class, sel_with_utf8, "hi".ptr);
msg_2 : (*void, *void) -> [*]u8 = xx objc_msgSend;
msg_2 : (*void, *void) -> [*]u8 callconv(.c) = xx objc_msgSend;
back := msg_2(ns_str, sel_utf8);
return xx (back[0] + back[1]); // 'h' + 'i' = 104 + 105 = 209

View File

@@ -34,7 +34,7 @@ main :: () -> s32 {
if obj == xx 0 { return 2; }
// [obj hello]
msg : (*void, *void) -> void = xx objc_msgSend;
msg : (*void, *void) -> void callconv(.c) = xx objc_msgSend;
msg(obj, sel_hello);
return g_marker; // 42 if hello_imp ran

View File

@@ -11,7 +11,7 @@
main :: () -> s32 {
cl := () => { print("noop block ran\n"); };
b : Block = xx cl;
invoke_fn : (*Block) -> void = xx b.invoke;
invoke_fn : (*Block) -> void callconv(.c) = xx b.invoke;
invoke_fn(@b);
0;
}

View File

@@ -11,7 +11,7 @@ main :: () -> s32 {
y : s64 = 100;
cl := () => { print("x + y = {}\n", x + y); };
b : Block = xx cl;
invoke_fn : (*Block) -> void = xx b.invoke;
invoke_fn : (*Block) -> void callconv(.c) = xx b.invoke;
invoke_fn(@b);
0;
}

View File

@@ -6,7 +6,7 @@
#import "modules/std/objc_block.sx";
invoke_once :: (b: *Block) {
invoke_fn : (*Block) -> void = xx b.invoke;
invoke_fn : (*Block) -> void callconv(.c) = xx b.invoke;
invoke_fn(b);
}

View File

@@ -22,13 +22,13 @@ ffi_apply_callback2 :: (cb: (*void, s32) -> s32, ctx: *void, v: s32) -> s32 #for
g_callback_hits : s32 = 0;
g_callback_sum : s32 = 0;
double_it :: (x: s32) -> s32 {
double_it :: (x: s32) -> s32 callconv(.c) {
g_callback_hits += 1;
g_callback_sum += x;
x * 2;
}
add_with_ctx :: (ctx: *void, v: s32) -> s32 {
add_with_ctx :: (ctx: *void, v: s32) -> s32 callconv(.c) {
g_callback_hits += 1;
// Pass a sentinel via ctx to prove the pointer arg also survives the
// round-trip — read it back as an s32 through *s32.

View File

@@ -1717,6 +1717,19 @@ pub const LLVMEmitter = struct {
break :blk false;
} else false;
// Default-conv fn-pointers under implicit-ctx carry a hidden
// `*void` (the implicit __sx_ctx) at LLVM slot 0. The IR fn
// type does not include it, so shift fn_params lookups by 1.
const fp_ctx_slots: usize = if (callee_ir_ty) |cty| blk: {
if (!self.ir_mod.has_implicit_ctx) break :blk 0;
if (cty.isBuiltin()) break :blk 0;
const ci = self.ir_mod.types.get(cty);
switch (ci) {
.function => |f| break :blk if (f.call_conv == .c) @as(usize, 0) else 1,
else => break :blk 0,
}
} else 0;
const ret_ty = if (callee_ir_ty) |cty| blk: {
if (!cty.isBuiltin()) {
const ci = self.ir_mod.types.get(cty);
@@ -1733,9 +1746,17 @@ pub const LLVMEmitter = struct {
defer self.alloc.free(param_tys);
if (fn_params) |fp| {
for (0..call_op.args.len) |j| {
if (j < fp.len) {
const raw_struct = self.toLLVMType(fp[j]);
if (fp_is_c_abi and self.needsByval(fp[j], raw_struct)) {
// Slots 0..fp_ctx_slots are the implicit __sx_ctx
// (passed as opaque ptr; not in fp).
if (j < fp_ctx_slots) {
param_tys[j] = self.cached_ptr;
args[j] = self.coerceArg(args[j], self.cached_ptr);
continue;
}
const fp_idx = j - fp_ctx_slots;
if (fp_idx < fp.len) {
const raw_struct = self.toLLVMType(fp[fp_idx]);
if (fp_is_c_abi and self.needsByval(fp[fp_idx], raw_struct)) {
args[j] = self.materializeByvalArg(args[j], raw_struct);
param_tys[j] = self.cached_ptr;
continue;
@@ -2294,7 +2315,18 @@ pub const LLVMEmitter = struct {
self.mapRef(c.LLVMGetUndef(self.toLLVMType(instruction.ty)));
},
.call_closure => |call_op| {
// Closure: { fn_ptr, env } — extract fn_ptr, prepend env as first arg
// Closure: { fn_ptr, env }.
//
// ABI (when module.has_implicit_ctx):
// trampoline signature: (__sx_ctx, env, args...)
// call_op.args[0] = __sx_ctx (prepended by lowering)
// call_op.args[1..] = user args
// extracted env_ptr = inserted at LLVM slot 1
//
// ABI (without implicit_ctx):
// trampoline signature: (env, args...)
// call_op.args = user args (no ctx prepend)
// extracted env_ptr = inserted at LLVM slot 0
const closure = self.resolveRef(call_op.callee);
const cl_kind = c.LLVMGetTypeKind(c.LLVMTypeOf(closure));
if (cl_kind != c.LLVMStructTypeKind) {
@@ -2314,36 +2346,44 @@ pub const LLVMEmitter = struct {
break :blk null;
} else null;
// Build args: env_ptr + call args
const total_args = call_op.args.len + 1;
const has_ctx = self.ir_mod.has_implicit_ctx;
const user_args_offset_in_op: usize = if (has_ctx) 1 else 0;
const user_args_count: usize = call_op.args.len -| user_args_offset_in_op;
const ctx_slots: usize = if (has_ctx) 1 else 0;
const total_args = ctx_slots + 1 + user_args_count; // [ctx?] + env + user_args
const args = self.alloc.alloc(c.LLVMValueRef, total_args) catch unreachable;
defer self.alloc.free(args);
args[0] = env_ptr;
for (call_op.args, 0..) |arg_ref, j| {
args[j + 1] = self.resolveRef(arg_ref);
if (has_ctx) {
args[0] = self.resolveRef(call_op.args[0]); // ctx
}
args[ctx_slots] = env_ptr;
for (0..user_args_count) |j| {
args[ctx_slots + 1 + j] = self.resolveRef(call_op.args[user_args_offset_in_op + j]);
}
// Build function type using declared param types (not arg types)
// Build function type using declared param types (not arg types).
// closure_params is user-visible (no ctx, no env), so they line
// up with args[ctx_slots+1..].
const ret_ty = self.toLLVMType(instruction.ty);
const param_tys = self.alloc.alloc(c.LLVMTypeRef, total_args) catch unreachable;
defer self.alloc.free(param_tys);
param_tys[0] = self.cached_ptr; // env
if (has_ctx) param_tys[0] = self.cached_ptr; // __sx_ctx
param_tys[ctx_slots] = self.cached_ptr; // env
if (closure_params) |cp| {
// Use declared closure param types and coerce args to match
// cp contains user-visible params only (no env)
for (0..call_op.args.len) |j| {
for (0..user_args_count) |j| {
const param_ir_ty = if (j < cp.len) cp[j] else null;
if (param_ir_ty) |pty| {
const llvm_pty = self.toLLVMType(pty);
param_tys[j + 1] = llvm_pty;
args[j + 1] = self.coerceArg(args[j + 1], llvm_pty);
param_tys[ctx_slots + 1 + j] = llvm_pty;
args[ctx_slots + 1 + j] = self.coerceArg(args[ctx_slots + 1 + j], llvm_pty);
} else {
param_tys[j + 1] = c.LLVMTypeOf(args[j + 1]);
param_tys[ctx_slots + 1 + j] = c.LLVMTypeOf(args[ctx_slots + 1 + j]);
}
}
} else {
for (args[1..], 0..) |arg, j| {
param_tys[j + 1] = c.LLVMTypeOf(arg);
for (0..user_args_count) |j| {
param_tys[ctx_slots + 1 + j] = c.LLVMTypeOf(args[ctx_slots + 1 + j]);
}
}
const fn_ty = c.LLVMFunctionType(ret_ty, param_tys.ptr, @intCast(total_args), 0);

View File

@@ -456,6 +456,12 @@ pub const Function = struct {
/// sites apply the standard default argument promotions (s8/s16/bool →
/// s32, f32 → f64) to extras past the fixed param count.
is_variadic: bool = false,
/// True if `params[0]` is the synthetic `__sx_ctx: *Context`
/// parameter that every default-conv sx function receives. Callers
/// read this flag to decide whether to prepend their current
/// `__sx_ctx` value to the args of a call. Foreign decls and
/// `callconv(.c)` functions have it false.
has_implicit_ctx: bool = false,
pub const Param = struct {
name: StringId,

View File

@@ -97,6 +97,16 @@ pub const Lowering = struct {
module_scopes: ?*std.StringHashMap(std.StringHashMap(void)) = null, // per-module visible names (from import resolution)
import_graph: ?*std.StringHashMap(std.StringHashMap(void)) = null, // module path → set of directly imported paths (used by param_impl_map visibility filter)
current_source_file: ?[]const u8 = null, // source file of function currently being lowered
// Implicit Context parameter machinery. When the program imports
// `std.sx` (and therefore declares `Context :: struct {...}`), every
// default-conv sx function gains a synthetic `__sx_ctx: *void` param
// at slot 0, and `current_ctx_ref` is bound to that param on each
// function-body entry. `lowerCall` / `call_indirect` prepend this ref
// to the args of every sx-to-sx call. push Context.{...} rebinds it
// to a stack-allocated Context for the lexical body. See
// `~/.claude/plans/lets-see-options-for-merry-dijkstra.md`.
implicit_ctx_enabled: bool = false,
current_ctx_ref: Ref = Ref.none,
sel_register_name_fid: ?FuncId = null, // lazily-declared `sel_registerName` extern (non-literal selector fallback)
jni_env_stack: std.ArrayList(Ref) = std.ArrayList(Ref).empty, // lexical `#jni_env(env)` Ref stack — top is current scope's env for omitted-env `#jni_call`
jni_env_stack_base: usize = 0, // index above which the currently-lowering fn's `#jni_env` scopes live; outer-fn Refs aren't valid in this fn's instruction stream
@@ -214,6 +224,13 @@ pub const Lowering = struct {
.root => |r| r.decls,
else => return,
};
// Pass 0: pre-scan for `Context :: struct {...}`. If the program
// imports `std.sx` it has Context, and every default-conv sx
// function gets the implicit `__sx_ctx` param. Otherwise the
// implicit-ctx machinery stays fully disabled — programs that
// call only libc directly keep their bare C ABI.
self.implicit_ctx_enabled = detectContextDecl(decls);
self.module.has_implicit_ctx = self.implicit_ctx_enabled;
// Pass 1: scan — register all function ASTs, struct types, extern stubs
self.scanDecls(decls);
// Pass 1b: inject compile-time constants (OS, ARCH, POINTER_SIZE) from target config
@@ -400,6 +417,55 @@ pub const Lowering = struct {
}
}
/// Detect whether `Context :: struct {...}` is declared anywhere in the
/// program. Used to gate the implicit `__sx_ctx` param machinery: when
/// `std.sx` is in the dep graph, `Context` is declared and every sx
/// function gets the implicit param. Otherwise the program runs with a
/// bare C ABI (no global Context, no implicit param, no FFI wrappers).
fn detectContextDecl(decls: []const *const Node) bool {
for (decls) |decl| {
const found = switch (decl.data) {
.struct_decl => |sd| std.mem.eql(u8, sd.name, "Context"),
.const_decl => |cd|
std.mem.eql(u8, cd.name, "Context") and cd.value.data == .struct_decl,
.namespace_decl => |ns| detectContextDecl(ns.decls),
else => false,
};
if (found) return true;
}
return false;
}
/// Returns true if a sx function declaration should receive the
/// implicit `__sx_ctx` parameter. False for foreign-libc bindings,
/// #builtin / #compiler bodies, and C-conv functions (which keep
/// their literal C ABI). Also false for OS-called entry points
/// (`isExportedEntryName`): main and JNI hooks are invoked by the
/// dyld / JVM with no `__sx_ctx` arg, so the visible signature must
/// not include one. Their bodies are still sx code — they
/// synthesise `&__sx_default_context` at entry and use it as their
/// own `current_ctx_ref`. Full FFI-wrapper split (a separate
/// `__sx_<name>_impl` with the ctx param) lands in Step 4 proper.
fn funcWantsImplicitCtx(self: *const Lowering, fd: *const ast.FnDecl) bool {
if (!self.implicit_ctx_enabled) return false;
if (fd.call_conv == .c) return false;
return switch (fd.body.data) {
.foreign_expr, .builtin_expr, .compiler_expr => false,
else => !isExportedEntryName(fd.name),
};
}
/// Returns true if a fn-pointer of the given type carries an implicit
/// `__sx_ctx` at LLVM slot 0. Default-conv sx fn-pointers do; C-conv
/// (and any non-function type) does not.
fn fnPtrTypeWantsCtx(self: *const Lowering, ty: TypeId) bool {
if (!self.implicit_ctx_enabled) return false;
if (ty.isBuiltin()) return false;
const ti = self.module.types.get(ty);
if (ti != .function) return false;
return ti.function.call_conv != .c;
}
/// Pass 1: Scan declarations — register ASTs and extern stubs, but don't lower bodies.
fn scanDecls(self: *Lowering, decls: []const *const Node) void {
for (decls) |decl| {
@@ -714,7 +780,14 @@ pub const Lowering = struct {
effective_params = fd.params[0 .. fd.params.len - 1];
}
const wants_ctx = self.funcWantsImplicitCtx(fd);
var params = std.ArrayList(Function.Param).empty;
if (wants_ctx) {
params.append(self.alloc, .{
.name = self.module.types.internString("__sx_ctx"),
.ty = self.module.types.ptrTo(.void),
}) catch unreachable;
}
for (effective_params) |p| {
const pty = self.resolveParamType(&p);
params.append(self.alloc, .{
@@ -735,6 +808,7 @@ pub const Lowering = struct {
func.call_conv = cc;
func.source_file = self.current_source_file;
func.is_variadic = is_variadic;
func.has_implicit_ctx = wants_ctx;
self.foreign_name_map.put(name, c_name) catch {};
return;
}
@@ -746,6 +820,7 @@ pub const Lowering = struct {
func.call_conv = cc;
func.source_file = self.current_source_file;
func.is_variadic = is_variadic;
func.has_implicit_ctx = wants_ctx;
}
/// Check if a C-imported function is visible from the current source file.
@@ -893,8 +968,11 @@ pub const Lowering = struct {
func.is_extern = false; // promote from extern stub to real function
func.linkage = if (isExportedEntryName(name)) .external else .internal;
if (fd.call_conv == .c) func.call_conv = .c;
// Set inst_counter to param count (params occupy refs 0..N-1)
std.debug.assert(func.params.len == fd.params.len); // AST and IR param counts must match
// Set inst_counter to param count (params occupy refs 0..N-1).
// IR params = AST params + 1 if the function carries `__sx_ctx`
// at slot 0.
const ctx_slots: usize = if (func.has_implicit_ctx) 1 else 0;
std.debug.assert(func.params.len == fd.params.len + ctx_slots);
self.builder.inst_counter = @intCast(func.params.len);
// Create entry block
@@ -907,14 +985,35 @@ pub const Lowering = struct {
defer scope.deinit();
self.scope = &scope;
// The implicit `__sx_ctx` param (when present) lives at slot 0;
// user params shift by one. `current_ctx_ref` is bound to slot 0
// so call-site lowering can prepend it to every sx-to-sx call.
// For OS-called entry points (main / JNI hooks), there's no
// ctx param at all — we synthesise `&__sx_default_context` and
// bind `current_ctx_ref` to its address so the body's sx-to-sx
// calls have a sensible Context to forward.
const wants_ctx = self.funcWantsImplicitCtx(fd);
const saved_ctx_ref = self.current_ctx_ref;
defer self.current_ctx_ref = saved_ctx_ref;
const user_param_base: u32 = if (wants_ctx) 1 else 0;
if (wants_ctx) self.current_ctx_ref = Ref.fromIndex(0);
for (fd.params, 0..) |p, i| {
const pty = self.resolveParamType(&p);
const slot = self.builder.alloca(pty);
const param_ref = Ref.fromIndex(@intCast(i));
const param_ref = Ref.fromIndex(@intCast(i + user_param_base));
self.builder.store(slot, param_ref);
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)) {
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));
}
}
// Auto-initialize context with default GPA at the start of main()
if (std.mem.eql(u8, name, "main")) {
self.emitDefaultContextInit();
@@ -964,8 +1063,16 @@ pub const Lowering = struct {
const name_id = self.module.types.internString(name);
const ret_ty = self.resolveReturnType(fd);
const wants_ctx = self.funcWantsImplicitCtx(fd);
// Build param list
var params = std.ArrayList(Function.Param).empty;
if (wants_ctx) {
params.append(self.alloc, .{
.name = self.module.types.internString("__sx_ctx"),
.ty = self.module.types.ptrTo(.void),
}) catch unreachable;
}
for (fd.params) |p| {
const pty = self.resolveParamType(&p);
params.append(self.alloc, .{
@@ -982,13 +1089,15 @@ pub const Lowering = struct {
// Skip generic functions (they have type parameters and are templates, not concrete)
if (fd.type_params.len > 0) {
_ = self.builder.declareExtern(name_id, params.items, ret_ty);
const fid = self.builder.declareExtern(name_id, params.items, ret_ty);
self.module.getFunctionMut(fid).has_implicit_ctx = wants_ctx;
return;
}
// Imported functions: declare as extern (don't lower bodies from other files)
if (is_imported) {
_ = self.builder.declareExtern(name_id, params.items, ret_ty);
const fid = self.builder.declareExtern(name_id, params.items, ret_ty);
self.module.getFunctionMut(fid).has_implicit_ctx = wants_ctx;
return;
}
@@ -998,6 +1107,7 @@ pub const Lowering = struct {
ret_ty,
);
_ = func_id;
self.builder.currentFunc().has_implicit_ctx = wants_ctx;
// Set linkage. Default for fn defs is `internal` (LLVM DCE-friendly,
// matches C `static`). isExportedEntryName lists the names the OS
@@ -1023,16 +1133,32 @@ pub const Lowering = struct {
self.scope = &scope;
defer self.scope = scope.parent;
// Implicit `__sx_ctx` at slot 0 when funcWantsImplicitCtx is true;
// user params shift by one. Bind `current_ctx_ref` for call-site
// forwarding inside the body.
const wants_ctx_lf = self.funcWantsImplicitCtx(fd);
const saved_ctx_ref_lf = self.current_ctx_ref;
defer self.current_ctx_ref = saved_ctx_ref_lf;
const user_param_base_lf: u32 = if (wants_ctx_lf) 1 else 0;
if (wants_ctx_lf) self.current_ctx_ref = Ref.fromIndex(0);
for (fd.params, 0..) |p, i| {
const pty = self.resolveParamType(&p);
// Allocate stack slot for param, store initial value.
// Refs 0..N-1 are reserved for function parameters by beginFunction.
const slot = self.builder.alloca(pty);
const param_ref = Ref.fromIndex(@intCast(i));
const param_ref = Ref.fromIndex(@intCast(i + user_param_base_lf));
self.builder.store(slot, param_ref);
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)) {
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));
}
}
// Lower the function body, capturing the last expression's value for implicit return
const saved_target = self.target_type;
self.target_type = if (ret_ty != .void) ret_ty else null;
@@ -3216,8 +3342,10 @@ pub const Lowering = struct {
/// If a method's first param expects a pointer (*T) but we're passing T by value,
/// swap the first arg with the alloca address (implicit address-of).
fn fixupMethodReceiver(self: *Lowering, method_args: *std.ArrayList(Ref), func: *const Function, obj_node: *const Node, obj_ty: TypeId) void {
if (func.params.len == 0) return;
const first_param_ty = func.params[0].ty;
// Skip the implicit __sx_ctx param when inspecting the receiver slot.
const skip: usize = if (func.has_implicit_ctx) 1 else 0;
if (func.params.len <= skip) return;
const first_param_ty = func.params[skip].ty;
// Check if first param expects a pointer
if (!first_param_ty.isBuiltin()) {
const pi = self.module.types.get(first_param_ty);
@@ -4546,10 +4674,12 @@ pub const Lowering = struct {
}
if (self.resolveFuncByName(fn_name)) |fid| {
const func = &self.module.functions.items[@intFromEnum(fid)];
// Build closure type from function signature
// Build closure type from user-visible params only —
// skip the implicit __sx_ctx param.
var param_types_list = std.ArrayList(TypeId).empty;
defer param_types_list.deinit(self.alloc);
for (func.params) |p| {
const skip: usize = if (func.has_implicit_ctx) 1 else 0;
for (func.params[skip..]) |p| {
param_types_list.append(self.alloc, p.ty) catch unreachable;
}
const closure_ty = self.module.types.closureType(param_types_list.items, func.ret);
@@ -4731,7 +4861,16 @@ pub const Lowering = struct {
const ty_info = self.module.types.get(binding.ty);
if (ty_info == .closure) {
const callee_ref = if (binding.is_alloca) self.builder.load(binding.ref, binding.ty) else binding.ref;
const owned = self.alloc.dupe(Ref, args.items) catch unreachable;
// Closure trampolines carry `__sx_ctx` at
// slot 0; emit_llvm's `call_closure` builds
// the call as [ctx, env, user_args], so we
// prepend ctx here. args[0] becomes ctx.
const owned = if (self.implicit_ctx_enabled) blk: {
const arr = self.alloc.alloc(Ref, args.items.len + 1) catch unreachable;
arr[0] = self.current_ctx_ref;
@memcpy(arr[1..], args.items);
break :blk arr;
} else self.alloc.dupe(Ref, args.items) catch unreachable;
const ret_ty = ty_info.closure.ret;
return self.builder.emit(.{ .call_closure = .{ .callee = callee_ref, .args = owned } }, ret_ty);
}
@@ -4771,21 +4910,28 @@ pub const Lowering = struct {
if (self.fn_ast_map.get(func_name)) |fd| {
self.packVariadicCallArgs(fd, c, &args);
}
const final_args = self.prependCtxIfNeeded(func, args.items);
// Coerce arguments to match parameter types
self.coerceCallArgs(args.items, params);
if (func.is_variadic) self.promoteCVariadicArgs(args.items, params.len);
return self.builder.call(fid, args.items, ret_ty);
self.coerceCallArgs(final_args, params);
if (func.is_variadic) self.promoteCVariadicArgs(final_args, params.len);
return self.builder.call(fid, final_args, ret_ty);
}
}
// May be a variable holding a function pointer (non-closure)
if (self.scope) |scope| {
if (scope.lookup(id.name)) |binding| {
const callee_ref = if (binding.is_alloca) self.builder.load(binding.ref, binding.ty) else binding.ref;
const owned = self.alloc.dupe(Ref, args.items) catch unreachable;
const ret_ty = if (!binding.ty.isBuiltin()) blk: {
const bti = self.module.types.get(binding.ty);
break :blk if (bti == .function) bti.function.ret else .s64;
} else .s64;
var final_args = std.ArrayList(Ref).empty;
defer final_args.deinit(self.alloc);
if (self.fnPtrTypeWantsCtx(binding.ty)) {
final_args.append(self.alloc, self.current_ctx_ref) catch unreachable;
}
final_args.appendSlice(self.alloc, args.items) catch unreachable;
const owned = self.alloc.dupe(Ref, final_args.items) catch unreachable;
return self.builder.emit(.{ .call_indirect = .{ .callee = callee_ref, .args = owned } }, ret_ty);
}
}
@@ -4825,7 +4971,13 @@ pub const Lowering = struct {
arg.* = self.coerceToType(arg.*, src_ty, dst_ty);
}
}
const owned = self.alloc.dupe(Ref, args.items) catch unreachable;
var final_args = std.ArrayList(Ref).empty;
defer final_args.deinit(self.alloc);
if (self.fnPtrTypeWantsCtx(gi.ty)) {
final_args.append(self.alloc, self.current_ctx_ref) catch unreachable;
}
final_args.appendSlice(self.alloc, args.items) catch unreachable;
const owned = self.alloc.dupe(Ref, final_args.items) catch unreachable;
return self.builder.emit(.{ .call_indirect = .{ .callee = callee_ref, .args = owned } }, gti.function.ret);
}
}
@@ -4886,8 +5038,9 @@ pub const Lowering = struct {
}
if (self.resolveFuncByName(mangled)) |fid| {
const func = &self.module.functions.items[@intFromEnum(fid)];
self.coerceCallArgs(args.items, func.params);
return self.builder.call(fid, args.items, func.ret);
const final_args = self.prependCtxIfNeeded(func, args.items);
self.coerceCallArgs(final_args, func.params);
return self.builder.call(fid, final_args, func.ret);
}
}
}
@@ -4981,9 +5134,10 @@ pub const Lowering = struct {
if (self.fn_ast_map.get(effective_name)) |fd| {
self.packVariadicCallArgs(fd, c, &args);
}
self.coerceCallArgs(args.items, params);
if (func.is_variadic) self.promoteCVariadicArgs(args.items, params.len);
return self.builder.call(fid, args.items, ret_ty);
const final_args = self.prependCtxIfNeeded(func, args.items);
self.coerceCallArgs(final_args, params);
if (func.is_variadic) self.promoteCVariadicArgs(final_args, params.len);
return self.builder.call(fid, final_args, ret_ty);
}
// Check if this is Type.variant(payload) — qualified enum construction
if (ns_name) |type_name| {
@@ -5045,7 +5199,13 @@ pub const Lowering = struct {
agg = self.builder.load(obj, oi.pointer.pointee);
}
const closure_val = self.builder.structGet(agg, @intCast(fi), f.ty);
const owned = self.alloc.dupe(Ref, args.items) catch unreachable;
// Prepend ctx for sx-side closure call ABI.
const owned = if (self.implicit_ctx_enabled) blk: {
const arr = self.alloc.alloc(Ref, args.items.len + 1) catch unreachable;
arr[0] = self.current_ctx_ref;
@memcpy(arr[1..], args.items);
break :blk arr;
} else self.alloc.dupe(Ref, args.items) catch unreachable;
return self.builder.emit(.{ .call_closure = .{ .callee = closure_val, .args = owned } }, fti.closure.ret);
}
}
@@ -5125,8 +5285,9 @@ pub const Lowering = struct {
const ret_ty = func.ret;
const params = func.params;
self.fixupMethodReceiver(&method_args, func, effective_obj_node, obj_ty);
self.coerceCallArgs(method_args.items, params);
return self.builder.call(fid, method_args.items, ret_ty);
const final_args = self.prependCtxIfNeeded(func, method_args.items);
self.coerceCallArgs(final_args, params);
return self.builder.call(fid, final_args, ret_ty);
}
}
}
@@ -5173,8 +5334,9 @@ pub const Lowering = struct {
arg_idx += 1;
}
self.fixupMethodReceiver(&gvalue_args, gfunc, effective_obj_node, obj_ty);
self.coerceCallArgs(gvalue_args.items, gparams);
return self.builder.call(gfid, gvalue_args.items, gret_ty);
const final_args = self.prependCtxIfNeeded(gfunc, gvalue_args.items);
self.coerceCallArgs(final_args, gparams);
return self.builder.call(gfid, final_args, gret_ty);
}
}
}
@@ -5190,19 +5352,30 @@ pub const Lowering = struct {
const func = &self.module.functions.items[@intFromEnum(fid)];
const ret_ty = func.ret;
const params = func.params;
const has_ctx = func.has_implicit_ctx;
self.fixupMethodReceiver(&method_args, func, effective_obj_node, obj_ty);
// Note: coerceCallArgs can trigger protocol thunk creation
// (module.addFunction), invalidating func pointer.
// Use pre-extracted params/ret_ty instead of func.* after this.
self.coerceCallArgs(method_args.items, params);
return self.builder.call(fid, method_args.items, ret_ty);
// Use pre-extracted params/ret_ty (+ has_ctx) instead of
// func.* after this.
const final_args = blk: {
if (!has_ctx) break :blk method_args.items;
const new_args = self.alloc.alloc(Ref, method_args.items.len + 1) catch break :blk method_args.items;
new_args[0] = self.current_ctx_ref;
@memcpy(new_args[1..], method_args.items);
break :blk new_args;
};
self.coerceCallArgs(final_args, params);
return self.builder.call(fid, final_args, ret_ty);
}
}
// Try to resolve as bare function name (method)
if (self.resolveFuncByName(fa.field)) |fid| {
const ret_ty = self.module.functions.items[@intFromEnum(fid)].ret;
return self.builder.call(fid, method_args.items, ret_ty);
const func = &self.module.functions.items[@intFromEnum(fid)];
const ret_ty = func.ret;
const final_args = self.prependCtxIfNeeded(func, method_args.items);
return self.builder.call(fid, final_args, ret_ty);
}
return self.emitError(fa.field, c.callee.span);
},
@@ -5228,8 +5401,9 @@ pub const Lowering = struct {
const func = &self.module.functions.items[@intFromEnum(fid)];
const ret_ty = func.ret;
const params = func.params;
self.coerceCallArgs(args.items, params);
return self.builder.call(fid, args.items, ret_ty);
const final_args = self.prependCtxIfNeeded(func, args.items);
self.coerceCallArgs(final_args, params);
return self.builder.call(fid, final_args, ret_ty);
}
}
}
@@ -5299,7 +5473,14 @@ pub const Lowering = struct {
// field 0 = receiver ctx, field 1 = alloc fn-ptr.
const alloc_ctx = self.builder.structGet(allocator, 0, void_ptr_ty);
const fn_ptr = self.builder.structGet(allocator, 1, void_ptr_ty);
const args = self.alloc.dupe(Ref, &.{ alloc_ctx, size_ref }) catch unreachable;
// Allocator thunks are sx-side and carry the implicit __sx_ctx at
// slot 0. Forward our caller's current_ctx_ref so the thunk's body
// (and the concrete alloc method it forwards to) has a real
// Context to thread on.
const args = if (self.implicit_ctx_enabled)
self.alloc.dupe(Ref, &.{ self.current_ctx_ref, alloc_ctx, size_ref }) catch unreachable
else
self.alloc.dupe(Ref, &.{ alloc_ctx, size_ref }) catch unreachable;
return self.builder.emit(.{ .call_indirect = .{
.callee = fn_ptr,
.args = args,
@@ -5315,6 +5496,22 @@ pub const Lowering = struct {
return self.builder.call(fid, args, ret_ty);
}
/// Prepend the caller's current `__sx_ctx` to `args` when the callee
/// has the implicit context param. Returns either the original `args`
/// (when no prepend is needed) or a newly-allocated slice with ctx at
/// slot 0. The returned slice is mutable so callers can pass it
/// straight into `coerceCallArgs`. Direct callers that built the args
/// themselves with __sx_ctx already prepended (protocol thunks, FFI
/// wrappers in Step 4) should NOT call this — they already manage
/// slot 0.
fn prependCtxIfNeeded(self: *Lowering, callee: *const Function, args: []Ref) []Ref {
if (!callee.has_implicit_ctx) return args;
const new_args = self.alloc.alloc(Ref, args.len + 1) catch return args;
new_args[0] = self.current_ctx_ref;
@memcpy(new_args[1..], args);
return new_args;
}
/// Pattern-match `context.allocator.alloc(size)` → heap_alloc,
/// `context.allocator.dealloc(ptr)` → heap_free.
fn matchContextAllocCall(self: *Lowering, fa: ast.FieldAccess, call_args: []const Ref) ?Ref {
@@ -5433,9 +5630,20 @@ pub const Lowering = struct {
const saved_counter = self.builder.inst_counter;
const saved_scope = self.scope;
// Build param list — trampoline convention: env: *void is first param
// Build param list. Convention when implicit_ctx is enabled:
// slot 0 = __sx_ctx: *void
// slot 1 = env: *void
// slot 2+ = user params
// Without implicit_ctx, env is slot 0 and user params follow.
var params = std.ArrayList(Function.Param).empty;
const env_ptr_ty = self.module.types.ptrTo(.void);
const lambda_wants_ctx = self.implicit_ctx_enabled and lam.call_conv != .c;
if (lambda_wants_ctx) {
params.append(self.alloc, .{
.name = self.module.types.internString("__sx_ctx"),
.ty = env_ptr_ty,
}) catch unreachable;
}
params.append(self.alloc, .{
.name = self.module.types.internString("env"),
.ty = env_ptr_ty,
@@ -5508,6 +5716,19 @@ pub const Lowering = struct {
if (lam.call_conv == .c) {
self.module.getFunctionMut(func_id).call_conv = .c;
}
self.builder.currentFunc().has_implicit_ctx = lambda_wants_ctx;
// Param-slot layout: ctx at 0 (if present), env at ctx_slots,
// user args at ctx_slots+1.
const lambda_ctx_slots: u32 = if (lambda_wants_ctx) 1 else 0;
const env_param_idx: u32 = lambda_ctx_slots;
const user_param_base_lam: u32 = lambda_ctx_slots + 1;
// Save + rebind current_ctx_ref so the body's sx-to-sx calls
// forward the trampoline's own ctx (slot 0).
const saved_ctx_ref_lam = self.current_ctx_ref;
defer self.current_ctx_ref = saved_ctx_ref_lam;
if (lambda_wants_ctx) self.current_ctx_ref = Ref.fromIndex(0);
// Create entry block
const entry_name = self.module.types.internString("entry");
@@ -5518,9 +5739,9 @@ pub const Lowering = struct {
var lambda_scope = Scope.init(self.alloc, null);
self.scope = &lambda_scope;
// Bind captures from env struct (param 0)
// Bind captures from env struct (at env_param_idx)
if (capture_list.len > 0) {
const env_param_ref = @as(Ref, @enumFromInt(0));
const env_param_ref = Ref.fromIndex(env_param_idx);
// Alloca env struct locally so struct_gep can resolve the type
const env_local = self.builder.alloca(env_struct_ty);
// Compute env size
@@ -5555,11 +5776,11 @@ pub const Lowering = struct {
}
}
// Bind params
// Bind params (user args start at user_param_base_lam, shifted past ctx + env)
for (lam.params, 0..) |p, i| {
const pty = self.resolveParamType(&p);
const slot = self.builder.alloca(pty);
const param_ref = @as(Ref, @enumFromInt(i + 1)); // +1: env is param 0
const param_ref = Ref.fromIndex(user_param_base_lam + @as(u32, @intCast(i)));
self.builder.store(slot, param_ref);
lambda_scope.put(p.name, .{ .ref = slot, .ty = pty, .is_alloca = true });
}
@@ -5586,9 +5807,10 @@ pub const Lowering = struct {
self.builder.current_block = saved_block;
self.builder.inst_counter = saved_counter;
// Create proper closure type (user-visible params only, no env)
// Create proper closure type (user-visible params only — skip ctx + env).
const skip_count: usize = if (lambda_wants_ctx) 2 else 1;
var param_types_list = std.ArrayList(TypeId).empty;
for (params.items[1..]) |p| { // skip env (index 0)
for (params.items[skip_count..]) |p| {
param_types_list.append(self.alloc, p.ty) catch unreachable;
}
const closure_ty = self.module.types.closureType(param_types_list.items, ret_ty);
@@ -5626,11 +5848,19 @@ pub const Lowering = struct {
/// The trampoline has signature `(env: *void, args...) -> ret` and simply calls the
/// bare function with `(args...)`, ignoring the env parameter.
fn createBareFnTrampoline(self: *Lowering, bare_func_id: FuncId, closure_info: types.TypeInfo.ClosureInfo) FuncId {
// Build trampoline params: env + closure params
// Build trampoline params: [__sx_ctx]? + env + closure params.
// When the program uses Context, every sx-side trampoline carries
// the implicit ctx at slot 0 and forwards it to the wrapped
// function (which is also sx-side and expects it at slot 0).
var params = std.ArrayList(inst_mod.Function.Param).empty;
defer params.deinit(self.alloc);
const void_ptr_ty = self.module.types.ptrTo(.void);
const wants_ctx = self.implicit_ctx_enabled;
if (wants_ctx) {
params.append(self.alloc, .{ .name = self.module.types.internString("__sx_ctx"), .ty = void_ptr_ty }) catch unreachable;
}
const env_name = self.module.types.internString("env");
params.append(self.alloc, .{ .name = env_name, .ty = self.module.types.ptrTo(.void) }) catch unreachable;
params.append(self.alloc, .{ .name = env_name, .ty = void_ptr_ty }) catch unreachable;
for (closure_info.params, 0..) |pty, i| {
var buf: [32]u8 = undefined;
const pname = std.fmt.bufPrint(&buf, "a{d}", .{i}) catch "arg";
@@ -5651,7 +5881,8 @@ pub const Lowering = struct {
// Create function
const owned_params = self.alloc.dupe(inst_mod.Function.Param, params.items) catch unreachable;
const func = inst_mod.Function.init(tramp_name_id, owned_params, closure_info.ret);
var func = inst_mod.Function.init(tramp_name_id, owned_params, closure_info.ret);
func.has_implicit_ctx = wants_ctx;
const func_id = self.module.addFunction(func);
self.builder.func = func_id;
self.builder.inst_counter = @intCast(owned_params.len); // params occupy refs 0..N-1
@@ -5659,11 +5890,17 @@ pub const Lowering = struct {
const entry_block = self.builder.appendBlock(entry_name, &.{});
self.builder.switchToBlock(entry_block);
// Build call args: skip env (param 0), forward params 1..N
// Build call args: forward [__sx_ctx]? + user_params (skip env).
// Trampoline slots: 0=ctx (if present), {0|1}=env, then user args.
const ctx_slots: usize = if (wants_ctx) 1 else 0;
const user_arg_start: u32 = @intCast(ctx_slots + 1); // skip ctx + env
var call_args = std.ArrayList(Ref).empty;
defer call_args.deinit(self.alloc);
if (wants_ctx and bare_func.has_implicit_ctx) {
call_args.append(self.alloc, Ref.fromIndex(0)) catch unreachable; // forward our ctx
}
for (closure_info.params, 0..) |_, i| {
call_args.append(self.alloc, Ref.fromIndex(@intCast(i + 1))) catch unreachable;
call_args.append(self.alloc, Ref.fromIndex(user_arg_start + @as(u32, @intCast(i)))) catch unreachable;
}
const owned_args = self.alloc.dupe(Ref, call_args.items) catch unreachable;
const result = self.builder.emit(.{ .call = .{ .callee = bare_func_id, .args = owned_args } }, closure_info.ret);
@@ -6117,7 +6354,12 @@ pub const Lowering = struct {
const func_id = self.createComptimeFunction("__ct", expr, ret_ty);
// Emit a call to the comptime function. At interpretation time,
// this will be evaluated and the result inlined as a constant.
return self.builder.call(func_id, &.{}, ret_ty);
const func = &self.module.functions.items[@intFromEnum(func_id)];
const final_args: []const Ref = if (func.has_implicit_ctx)
self.alloc.dupe(Ref, &.{self.current_ctx_ref}) catch &.{}
else
&.{};
return self.builder.call(func_id, final_args, ret_ty);
}
/// Lower a `#insert expr` statement. Evaluates `expr` at compile time to get
@@ -6671,8 +6913,9 @@ pub const Lowering = struct {
}
arg_idx += 1;
}
self.coerceCallArgs(value_args.items, params);
return self.builder.call(fid, value_args.items, ret_ty);
const final_args = self.prependCtxIfNeeded(func, value_args.items);
self.coerceCallArgs(final_args, params);
return self.builder.call(fid, final_args, ret_ty);
}
return self.emitError(base_name, call_node.callee.span);
@@ -6883,8 +7126,9 @@ pub const Lowering = struct {
}
}
}
self.coerceCallArgs(call_args.items, callee_params);
const result = self.builder.call(fid, call_args.items, callee_ret);
const final_args = self.prependCtxIfNeeded(func, call_args.items);
self.coerceCallArgs(final_args, callee_params);
const result = self.builder.call(fid, final_args, callee_ret);
if (result_slot) |slot| {
self.builder.store(slot, result);
}
@@ -6896,16 +7140,20 @@ pub const Lowering = struct {
self.lazyLowerFunction(resolve_name);
}
if (self.resolveFuncByName(resolve_name)) |fid| {
const callee_ret = self.module.functions.items[@intFromEnum(fid)].ret;
const callee_params = self.module.functions.items[@intFromEnum(fid)].params;
const callee_func = &self.module.functions.items[@intFromEnum(fid)];
const callee_ret = callee_func.ret;
const callee_params = callee_func.params;
const callee_has_ctx = callee_func.has_implicit_ctx;
var call_args = std.ArrayList(Ref).empty;
defer call_args.deinit(self.alloc);
for (fd.params, 0..) |_, pi| {
if (pi == cast_arg_idx) {
// Coerce unboxed value (typed as ty_id) to param type
var arg = unboxed;
if (pi < callee_params.len) {
arg = self.coerceToType(arg, ty_id, callee_params[pi].ty);
// callee param index shifts by +1 if it carries __sx_ctx
const callee_pi = pi + @as(usize, if (callee_has_ctx) 1 else 0);
if (callee_pi < callee_params.len) {
arg = self.coerceToType(arg, ty_id, callee_params[callee_pi].ty);
}
call_args.append(self.alloc, arg) catch unreachable;
} else if (pi < other_args.items.len) {
@@ -6914,13 +7162,25 @@ pub const Lowering = struct {
}
}
}
// Coerce non-cast args (source type unknown, use s64 default)
for (0..@min(call_args.items.len, callee_params.len)) |ci| {
if (ci != cast_arg_idx) {
call_args.items[ci] = self.coerceToType(call_args.items[ci], .s64, callee_params[ci].ty);
// Prepend __sx_ctx if needed BEFORE coercion so indices line up.
var final_call_args: []Ref = call_args.items;
if (callee_has_ctx) {
final_call_args = self.alloc.alloc(Ref, call_args.items.len + 1) catch call_args.items;
if (final_call_args.len == call_args.items.len + 1) {
final_call_args[0] = self.current_ctx_ref;
@memcpy(final_call_args[1..], call_args.items);
}
}
const result = self.builder.call(fid, call_args.items, callee_ret);
// Coerce non-cast args (source type unknown, use s64 default).
// cast_arg_idx is in user-space (skips __sx_ctx); offset by ctx_slots.
const ctx_slots: usize = if (callee_has_ctx) 1 else 0;
for (0..@min(final_call_args.len, callee_params.len)) |ci| {
if (ci < ctx_slots) continue; // skip __sx_ctx slot
if ((ci - ctx_slots) != cast_arg_idx) {
final_call_args[ci] = self.coerceToType(final_call_args[ci], .s64, callee_params[ci].ty);
}
}
const result = self.builder.call(fid, final_call_args, callee_ret);
if (result_slot) |slot| {
self.builder.store(slot, result);
}
@@ -6975,8 +7235,19 @@ pub const Lowering = struct {
const ret_ty = self.resolveReturnType(fd);
self.target_type = ret_ty;
// Build param list (substituting type params, skipping type param declarations)
const wants_ctx = self.funcWantsImplicitCtx(fd);
const saved_ctx_ref_mono = self.current_ctx_ref;
defer self.current_ctx_ref = saved_ctx_ref_mono;
// Build param list (substituting type params, skipping type param declarations).
// Prepend `__sx_ctx: *void` at slot 0 if the function gets the implicit param.
var params = std.ArrayList(Function.Param).empty;
if (wants_ctx) {
params.append(self.alloc, .{
.name = self.module.types.internString("__sx_ctx"),
.ty = self.module.types.ptrTo(.void),
}) catch unreachable;
}
for (fd.params) |p| {
if (isTypeParamDecl(&p, fd.type_params)) continue;
const pty = self.resolveParamType(&p);
@@ -6990,11 +7261,13 @@ pub const Lowering = struct {
const name_id = self.module.types.internString(owned_name);
const func_id = self.builder.beginFunction(name_id, params.items, ret_ty);
_ = func_id;
self.builder.currentFunc().has_implicit_ctx = wants_ctx;
// Create entry block
const entry_name = self.module.types.internString("entry");
const entry = self.builder.appendBlock(entry_name, &.{});
self.builder.switchToBlock(entry);
if (wants_ctx) self.current_ctx_ref = Ref.fromIndex(0);
// Create scope and bind params
var scope = Scope.init(self.alloc, null);
@@ -7002,7 +7275,7 @@ pub const Lowering = struct {
self.scope = &scope;
{
var param_idx: u32 = 0;
var param_idx: u32 = if (wants_ctx) 1 else 0;
for (fd.params) |p| {
if (isTypeParamDecl(&p, fd.type_params)) continue;
const pty = self.resolveParamType(&p);
@@ -7683,6 +7956,21 @@ pub const Lowering = struct {
/// Resolve parameter types for a call expression (for target_type context).
/// Returns empty slice if the function can't be resolved.
/// Return the param types of a Function from the caller's POV — i.e.
/// skipping the synthetic `__sx_ctx` slot when present. lowerCall's
/// arg-lowering uses these to set `target_type` per arg, and user
/// args don't include `__sx_ctx`, so the slot must be elided.
fn userParamTypes(self: *Lowering, func: *const Function) []TypeId {
const start: usize = if (func.has_implicit_ctx) 1 else 0;
var types_list = std.ArrayList(TypeId).empty;
if (func.params.len > start) {
for (func.params[start..]) |p| {
types_list.append(self.alloc, p.ty) catch unreachable;
}
}
return types_list.items;
}
fn resolveCallParamTypes(self: *Lowering, c: *const ast.Call) []const TypeId {
// Method calls: obj.method(args) — resolve param types from the method signature,
// skipping the first param (self) since it's prepended later.
@@ -7707,11 +7995,7 @@ pub const Lowering = struct {
const qualified = std.fmt.allocPrint(self.alloc, "{s}.{s}", .{ obj_name, fa.field }) catch return &.{};
if (self.resolveFuncByName(qualified)) |fid| {
const func = &self.module.functions.items[@intFromEnum(fid)];
var types_list = std.ArrayList(TypeId).empty;
for (func.params) |p| {
types_list.append(self.alloc, p.ty) catch unreachable;
}
return types_list.items;
return self.userParamTypes(func);
}
if (self.fn_ast_map.get(qualified)) |fd| {
var types_list = std.ArrayList(TypeId).empty;
@@ -7762,10 +8046,12 @@ pub const Lowering = struct {
// Try already-lowered functions first
if (self.resolveFuncByName(qualified)) |fid| {
const func = &self.module.functions.items[@intFromEnum(fid)];
if (func.params.len > 0) {
// Skip self param — caller args don't include self
// Skip both `__sx_ctx` (if present) AND `self` param;
// caller args include neither.
const skip: usize = (if (func.has_implicit_ctx) @as(usize, 1) else 0) + 1;
if (func.params.len > skip) {
var types_list = std.ArrayList(TypeId).empty;
for (func.params[1..]) |p| {
for (func.params[skip..]) |p| {
types_list.append(self.alloc, p.ty) catch unreachable;
}
return types_list.items;
@@ -7817,12 +8103,7 @@ pub const Lowering = struct {
// Check declared functions
if (self.resolveFuncByName(name)) |fid| {
const func = &self.module.functions.items[@intFromEnum(fid)];
// Return param types (allocated as slice of TypeId)
var types_list = std.ArrayList(TypeId).empty;
for (func.params) |p| {
types_list.append(self.alloc, p.ty) catch unreachable;
}
return types_list.items;
return self.userParamTypes(func);
}
// Check AST map for function signatures
@@ -7888,18 +8169,39 @@ pub const Lowering = struct {
const saved_block = self.builder.current_block;
const saved_counter = self.builder.inst_counter;
const saved_scope = self.scope;
const saved_ctx_ref = self.current_ctx_ref;
defer self.current_ctx_ref = saved_ctx_ref;
// Create the comptime function (no params, returns ret_ty)
// Build params: implicit `__sx_ctx` at slot 0 when the program
// uses Context (so the body's `context.X` reads + transitive calls
// resolve cleanly). The comptime function's top-level invocation
// supplies `&__sx_default_context` (interp via callWithDefaultContext;
// codegen via the comptime-eval glue in emit_llvm).
const wants_ctx = self.implicit_ctx_enabled;
const params_slice = blk: {
if (!wants_ctx) break :blk &[_]Function.Param{};
const owned = self.alloc.alloc(Function.Param, 1) catch break :blk &[_]Function.Param{};
owned[0] = .{
.name = self.module.types.internString("__sx_ctx"),
.ty = self.module.types.ptrTo(.void),
};
break :blk owned;
};
// Create the comptime function
const name_id = self.module.types.internString(name);
const func_id = self.builder.beginFunction(name_id, &.{}, ret_ty);
const func_id = self.builder.beginFunction(name_id, params_slice, ret_ty);
// Mark as comptime
self.module.getFunctionMut(func_id).is_comptime = true;
// Mark as comptime + has_implicit_ctx
const fn_mut = self.module.getFunctionMut(func_id);
fn_mut.is_comptime = true;
fn_mut.has_implicit_ctx = wants_ctx;
// Create entry block
const entry_name = self.module.types.internString("entry");
const entry = self.builder.appendBlock(entry_name, &.{});
self.builder.switchToBlock(entry);
if (wants_ctx) self.current_ctx_ref = Ref.fromIndex(0);
// Create a scope that chains to the enclosing scope (so the
// expression can reference names visible at the #run site).
@@ -9078,10 +9380,17 @@ pub const Lowering = struct {
/// Create a thunk function: __thunk_ConcreteType_Protocol_method(ctx: *void, args...) -> ret
/// The thunk calls ConcreteType.method(ctx, args...).
fn createProtocolThunk(self: *Lowering, proto_name: []const u8, concrete_type_name: []const u8, method: ProtocolMethodInfo) FuncId {
// Build params: ctx: *void + method params
// Build params: [__sx_ctx]? + ctx: *void + method params.
// Thunks are sx-side functions, so they get the implicit __sx_ctx
// at slot 0 when it's enabled program-wide. The concrete protocol
// receiver (ctx) follows at slot 1; user method args at slot 2+.
var params = std.ArrayList(inst_mod.Function.Param).empty;
defer params.deinit(self.alloc);
const void_ptr = self.module.types.ptrTo(.void);
const thunk_has_ctx = self.implicit_ctx_enabled;
if (thunk_has_ctx) {
params.append(self.alloc, .{ .name = self.module.types.internString("__sx_ctx"), .ty = void_ptr }) catch unreachable;
}
params.append(self.alloc, .{ .name = self.module.types.internString("ctx"), .ty = void_ptr }) catch unreachable;
for (method.param_types, 0..) |pty, i| {
var buf: [32]u8 = undefined;
@@ -9098,12 +9407,16 @@ pub const Lowering = struct {
const saved_func = self.builder.func;
const saved_block = self.builder.current_block;
const saved_counter = self.builder.inst_counter;
const saved_ctx_ref_thunk = self.current_ctx_ref;
defer self.current_ctx_ref = saved_ctx_ref_thunk;
const owned_params = self.alloc.dupe(inst_mod.Function.Param, params.items) catch unreachable;
const func = inst_mod.Function.init(thunk_name_id, owned_params, method.ret_type);
var func = inst_mod.Function.init(thunk_name_id, owned_params, method.ret_type);
func.has_implicit_ctx = thunk_has_ctx;
const func_id = self.module.addFunction(func);
self.builder.func = func_id;
self.builder.inst_counter = @intCast(owned_params.len);
if (thunk_has_ctx) self.current_ctx_ref = Ref.fromIndex(0);
const entry_block = self.builder.appendBlock(self.module.types.internString("entry"), &.{});
self.builder.switchToBlock(entry_block);
@@ -9113,16 +9426,30 @@ pub const Lowering = struct {
self.lazyLowerFunction(qualified);
}
// Call the concrete method: ConcreteType.method(ctx, args...)
// Call the concrete method: ConcreteType.method(__sx_ctx?, ctx, args...).
// The concrete method is itself an sx function that takes the
// implicit __sx_ctx at slot 0 (when implicit_ctx is enabled); we
// forward the thunk's own __sx_ctx.
if (self.resolveFuncByName(qualified)) |concrete_fid| {
const concrete_func = &self.module.functions.items[@intFromEnum(concrete_fid)];
var call_args = std.ArrayList(Ref).empty;
defer call_args.deinit(self.alloc);
// Pass ctx (ref 0) as first arg (it's the concrete *Type disguised as *void)
// If the concrete method expects a value (e.g., f32) not a pointer, load from ctx
const ctx_ref = Ref.fromIndex(0);
if (concrete_func.params.len > 0) {
const first_concrete_ty = concrete_func.params[0].ty;
// Slot offsets inside the thunk: __sx_ctx at 0 (if present),
// protocol receiver (ctx) at slot user_base, user args at +1, +2...
const user_base: u32 = if (thunk_has_ctx) 1 else 0;
// Forward our __sx_ctx to the concrete method's __sx_ctx slot.
if (concrete_func.has_implicit_ctx) {
call_args.append(self.alloc, self.current_ctx_ref) catch unreachable;
}
// Pass ctx as the next arg (it's the concrete *Type disguised as *void).
// If the concrete method expects a value (e.g., f32) not a pointer, load from ctx.
const ctx_ref = Ref.fromIndex(user_base);
const concrete_receiver_idx: usize = if (concrete_func.has_implicit_ctx) 1 else 0;
if (concrete_receiver_idx < concrete_func.params.len) {
const first_concrete_ty = concrete_func.params[concrete_receiver_idx].ty;
const first_info = self.module.types.get(first_concrete_ty);
if (first_info != .pointer) {
// Concrete expects value — load from ctx pointer
@@ -9134,10 +9461,10 @@ pub const Lowering = struct {
call_args.append(self.alloc, ctx_ref) catch unreachable;
}
for (method.param_types, 0..) |proto_pty, i| {
var arg_ref = Ref.fromIndex(@intCast(i + 1));
var arg_ref = Ref.fromIndex(@intCast(user_base + 1 + i));
// If protocol param is a pointer (Self→*void) but concrete method
// expects a value type, load the value from the pointer.
const concrete_idx = i + 1; // +1 for self/ctx
const concrete_idx = concrete_receiver_idx + 1 + i;
if (concrete_idx < concrete_func.params.len) {
const concrete_pty = concrete_func.params[concrete_idx].ty;
const proto_info = self.module.types.get(proto_pty);
@@ -9288,12 +9615,16 @@ pub const Lowering = struct {
};
_ = proto_ty;
// Build call args: ctx + user args
// Protocol method params use *void for Self-typed params. If the caller passes
// a struct value, we need to alloca+store and pass the pointer instead.
// Also coerce argument types to match declared param types (e.g., s64 → s32).
// Build call args: [__sx_ctx]? + receiver_ctx + user args.
// Protocol thunks are sx-side, so they carry the implicit __sx_ctx
// at slot 0 when the program uses Context — forward our caller's
// ctx so the thunk's body (and the concrete method it forwards to)
// sees the same Context as the dispatching code.
var call_args = std.ArrayList(Ref).empty;
defer call_args.deinit(self.alloc);
if (self.implicit_ctx_enabled) {
call_args.append(self.alloc, self.current_ctx_ref) catch unreachable;
}
call_args.append(self.alloc, ctx) catch unreachable;
for (args, 0..) |a, i| {
const expected_ty = if (i < mi.param_types.len) mi.param_types[i] else void_ptr;
@@ -9901,9 +10232,10 @@ pub const Lowering = struct {
const func = &self.module.functions.items[@intFromEnum(fid)];
const ret_ty = func.ret;
const params = func.params;
var args = [_]Ref{operand};
self.coerceCallArgs(args[0..], params);
return self.builder.call(fid, args[0..], ret_ty);
var single = [_]Ref{operand};
const final_args = self.prependCtxIfNeeded(func, single[0..]);
self.coerceCallArgs(final_args, params);
return self.builder.call(fid, final_args, ret_ty);
}
/// Build a protocol value from a concrete value via xx conversion.

View File

@@ -34,6 +34,11 @@ pub const Module = struct {
/// `lookupObjcSelector` / `appendObjcSelector` to read/write it.
objc_selector_cache: std.ArrayList(ObjcSelectorEntry),
alloc: Allocator,
/// True when this module's program imports `std.sx` (and therefore
/// has the `Context` type). Set by lowering's Pass 0 pre-scan. Read
/// by emit_llvm to decide whether closure/fn-pointer call sites
/// need `__sx_ctx` prepended to their LLVM args/types.
has_implicit_ctx: bool = false,
pub const ObjcSelectorEntry = struct { sel: []const u8, slot: GlobalId };

View File

@@ -1,4 +1,4 @@
a 0 : Foo{a: 0, b: 42, c: 92, d: 17}
a 0 : Foo{a: 0, b: 42, c: 0, d: 17}
a 1 : Foo{a: 1, b: 42, c: 8, d: 17}
b: Foo{a: 1, b: 1, c: 101, d: 1}
b: Foo{a: 1, b: 0, c: 101, d: 0}
Pack{a: 1, b: 0, c: 3, d: 5, f: 9, v: 100, x: 3.500000}

View File

@@ -23,39 +23,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -67,12 +67,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -84,55 +84,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -141,7 +141,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -156,27 +156,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -188,7 +188,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -210,16 +210,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -235,24 +235,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal void @unused_jni(ptr %0, ptr %1) #0 {
define internal void @unused_jni(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -263,23 +263,23 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %3, align 8
%jni.cls = call ptr %jni.GetObjectClass(ptr %load, ptr %loadN)
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %4, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %jni.cls)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_noop____V, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %5, align 8
%jni.fresh.mid = call ptr %jni.GetMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_noop____V, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 61
%jni.callfn = load ptr, ptr %5, align 8
%6 = getelementptr inbounds ptr, ptr %jni.ifs, i32 61
%jni.callfn = load ptr, ptr %6, align 8
call void %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid)
%loadN = load ptr, ptr %allocaN, align 8
%jni.ifs4 = load ptr, ptr %load, align 8
@@ -288,23 +288,23 @@ jni.cont: ; preds = %jni.miss, %entry
br i1 %jni.is.cached6, label %jni.cont8, label %jni.miss7
jni.miss7: ; preds = %jni.cont
%6 = getelementptr inbounds ptr, ptr %jni.ifs4, i32 31
%jni.GetObjectClass9 = load ptr, ptr %6, align 8
%7 = getelementptr inbounds ptr, ptr %jni.ifs4, i32 31
%jni.GetObjectClass9 = load ptr, ptr %7, align 8
%jni.cls10 = call ptr %jni.GetObjectClass9(ptr %load, ptr %loadN)
%7 = getelementptr inbounds ptr, ptr %jni.ifs4, i32 21
%jni.NewGlobalRef11 = load ptr, ptr %7, align 8
%8 = getelementptr inbounds ptr, ptr %jni.ifs4, i32 21
%jni.NewGlobalRef11 = load ptr, ptr %8, align 8
%jni.global.cls12 = call ptr %jni.NewGlobalRef11(ptr %load, ptr %jni.cls10)
store ptr %jni.global.cls12, ptr @SX_JNI_CLS_noop____V, align 8
%8 = getelementptr inbounds ptr, ptr %jni.ifs4, i32 33
%jni.GetMethodID13 = load ptr, ptr %8, align 8
%9 = getelementptr inbounds ptr, ptr %jni.ifs4, i32 33
%jni.GetMethodID13 = load ptr, ptr %9, align 8
%jni.fresh.mid14 = call ptr %jni.GetMethodID13(ptr %load, ptr %jni.global.cls12, ptr @str.2, ptr @str.3)
store ptr %jni.fresh.mid14, ptr @SX_JNI_MID_noop____V, align 8
br label %jni.cont8
jni.cont8: ; preds = %jni.miss7, %jni.cont
%jni.mid15 = phi ptr [ %jni.cached.mid5, %jni.cont ], [ %jni.fresh.mid14, %jni.miss7 ]
%9 = getelementptr inbounds ptr, ptr %jni.ifs4, i32 61
%jni.callfn16 = load ptr, ptr %9, align 8
%10 = getelementptr inbounds ptr, ptr %jni.ifs4, i32 61
%jni.callfn16 = load ptr, ptr %10, align 8
call void %jni.callfn16(ptr %load, ptr %loadN, ptr %jni.mid15)
call void @sx_jni_env_tl_set(ptr %call)
ret void
@@ -325,7 +325,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
call void @unused_jni(ptr null, ptr null)
call void @unused_jni(ptr @__sx_default_context, ptr null, ptr null)
br label %if.merge.1
if.merge.1: ; preds = %if.then.0, %entry
@@ -340,8 +340,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.5, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%call = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %call)
%call = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %call)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -351,30 +351,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -385,3 +385,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -21,39 +21,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -65,12 +65,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -82,55 +82,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -139,7 +139,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -154,27 +154,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -186,7 +186,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -208,16 +208,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -233,24 +233,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal i32 @read_int(ptr %0, ptr %1) #0 {
define internal i32 @read_int(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -261,23 +261,23 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %3, align 8
%jni.cls = call ptr %jni.GetObjectClass(ptr %load, ptr %loadN)
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %4, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %jni.cls)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_getCount____I, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %5, align 8
%jni.fresh.mid = call ptr %jni.GetMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_getCount____I, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 49
%jni.callfn = load ptr, ptr %5, align 8
%6 = getelementptr inbounds ptr, ptr %jni.ifs, i32 49
%jni.callfn = load ptr, ptr %6, align 8
%jni.ret = call i32 %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid)
call void @sx_jni_env_tl_set(ptr %call)
ret i32 %jni.ret
@@ -298,7 +298,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
%call = call i32 @read_int(ptr null, ptr null)
%call = call i32 @read_int(ptr @__sx_default_context, ptr null, ptr null)
%allocaN = alloca i32, align 4
store i32 %call, ptr %allocaN, align 4
br label %if.merge.1
@@ -315,8 +315,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.3, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%callN = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %callN)
%callN = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %callN)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -326,30 +326,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -360,3 +360,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -21,39 +21,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -65,12 +65,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -82,55 +82,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -139,7 +139,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -154,27 +154,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -186,7 +186,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -208,16 +208,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -233,24 +233,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal i64 @read_long(ptr %0, ptr %1) #0 {
define internal i64 @read_long(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -261,23 +261,23 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %3, align 8
%jni.cls = call ptr %jni.GetObjectClass(ptr %load, ptr %loadN)
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %4, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %jni.cls)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_currentTimeMillis____J, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %5, align 8
%jni.fresh.mid = call ptr %jni.GetMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_currentTimeMillis____J, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 52
%jni.callfn = load ptr, ptr %5, align 8
%6 = getelementptr inbounds ptr, ptr %jni.ifs, i32 52
%jni.callfn = load ptr, ptr %6, align 8
%jni.ret = call i64 %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid)
call void @sx_jni_env_tl_set(ptr %call)
ret i64 %jni.ret
@@ -298,7 +298,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
%call = call i64 @read_long(ptr null, ptr null)
%call = call i64 @read_long(ptr @__sx_default_context, ptr null, ptr null)
%allocaN = alloca i64, align 8
store i64 %call, ptr %allocaN, align 8
br label %if.merge.1
@@ -315,8 +315,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.3, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%callN = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %callN)
%callN = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %callN)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -326,30 +326,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -360,3 +360,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -21,39 +21,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -65,12 +65,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -82,55 +82,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -139,7 +139,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -154,27 +154,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -186,7 +186,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -208,16 +208,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -233,24 +233,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal double @read_double(ptr %0, ptr %1) #0 {
define internal double @read_double(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -261,23 +261,23 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %3, align 8
%jni.cls = call ptr %jni.GetObjectClass(ptr %load, ptr %loadN)
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %4, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %jni.cls)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_getValue____D, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %5, align 8
%jni.fresh.mid = call ptr %jni.GetMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_getValue____D, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 58
%jni.callfn = load ptr, ptr %5, align 8
%6 = getelementptr inbounds ptr, ptr %jni.ifs, i32 58
%jni.callfn = load ptr, ptr %6, align 8
%jni.ret = call double %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid)
call void @sx_jni_env_tl_set(ptr %call)
ret double %jni.ret
@@ -298,7 +298,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
%call = call double @read_double(ptr null, ptr null)
%call = call double @read_double(ptr @__sx_default_context, ptr null, ptr null)
%allocaN = alloca double, align 8
store double %call, ptr %allocaN, align 8
br label %if.merge.1
@@ -315,8 +315,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.3, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%callN = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %callN)
%callN = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %callN)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -326,30 +326,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -360,3 +360,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -21,39 +21,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -65,12 +65,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -82,55 +82,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -139,7 +139,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -154,27 +154,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -186,7 +186,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -208,16 +208,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -233,24 +233,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal i1 @read_bool(ptr %0, ptr %1) #0 {
define internal i1 @read_bool(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -261,23 +261,23 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %3, align 8
%jni.cls = call ptr %jni.GetObjectClass(ptr %load, ptr %loadN)
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %4, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %jni.cls)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_isShown____Z, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %5, align 8
%jni.fresh.mid = call ptr %jni.GetMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_isShown____Z, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 37
%jni.callfn = load ptr, ptr %5, align 8
%6 = getelementptr inbounds ptr, ptr %jni.ifs, i32 37
%jni.callfn = load ptr, ptr %6, align 8
%jni.ret = call i1 %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid)
call void @sx_jni_env_tl_set(ptr %call)
ret i1 %jni.ret
@@ -298,7 +298,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
%call = call i1 @read_bool(ptr null, ptr null)
%call = call i1 @read_bool(ptr @__sx_default_context, ptr null, ptr null)
%allocaN = alloca i1, align 1
store i1 %call, ptr %allocaN, align 1
br label %if.merge.1
@@ -315,8 +315,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.3, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%callN = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %callN)
%callN = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %callN)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -326,30 +326,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -360,3 +360,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -21,39 +21,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -65,12 +65,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -82,55 +82,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -139,7 +139,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -154,27 +154,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -186,7 +186,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -208,16 +208,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -233,24 +233,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal ptr @get_window(ptr %0, ptr %1) #0 {
define internal ptr @get_window(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -261,23 +261,23 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %3, align 8
%jni.cls = call ptr %jni.GetObjectClass(ptr %load, ptr %loadN)
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %4, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %jni.cls)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_getWindow____Landroid_view_Window_, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %5, align 8
%jni.fresh.mid = call ptr %jni.GetMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_getWindow____Landroid_view_Window_, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 34
%jni.callfn = load ptr, ptr %5, align 8
%6 = getelementptr inbounds ptr, ptr %jni.ifs, i32 34
%jni.callfn = load ptr, ptr %6, align 8
%jni.ret = call ptr %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid)
call void @sx_jni_env_tl_set(ptr %call)
ret ptr %jni.ret
@@ -298,7 +298,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
%call = call ptr @get_window(ptr null, ptr null)
%call = call ptr @get_window(ptr @__sx_default_context, ptr null, ptr null)
%allocaN = alloca ptr, align 8
store ptr %call, ptr %allocaN, align 8
br label %if.merge.1
@@ -315,8 +315,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.3, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%callN = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %callN)
%callN = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %callN)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -326,30 +326,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -360,3 +360,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -21,39 +21,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -65,12 +65,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -82,55 +82,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -139,7 +139,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -154,27 +154,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -186,7 +186,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -208,16 +208,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -233,24 +233,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal i32 @call_static_max(ptr %0, ptr %1) #0 {
define internal i32 @call_static_max(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -261,20 +261,20 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %loadN)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_max___II_I, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 113
%jni.GetStaticMethodID = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 113
%jni.GetStaticMethodID = load ptr, ptr %4, align 8
%jni.fresh.mid = call ptr %jni.GetStaticMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_max___II_I, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 129
%jni.callfn = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 129
%jni.callfn = load ptr, ptr %5, align 8
%jni.ret = call i32 %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid, i32 3, i32 7)
call void @sx_jni_env_tl_set(ptr %call)
ret i32 %jni.ret
@@ -295,7 +295,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
%call = call i32 @call_static_max(ptr null, ptr null)
%call = call i32 @call_static_max(ptr @__sx_default_context, ptr null, ptr null)
%allocaN = alloca i32, align 4
store i32 %call, ptr %allocaN, align 4
br label %if.merge.1
@@ -312,8 +312,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.3, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%callN = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %callN)
%callN = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %callN)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -323,30 +323,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -357,3 +357,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -21,39 +21,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -65,12 +65,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -82,55 +82,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -139,7 +139,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -154,27 +154,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -186,7 +186,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -208,16 +208,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -233,24 +233,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal void @unused_jni(ptr %0, ptr %1) #0 {
define internal void @unused_jni(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -261,23 +261,23 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %3, align 8
%jni.cls = call ptr %jni.GetObjectClass(ptr %load, ptr %loadN)
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %4, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %jni.cls)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_getWindow____Ljava_lang_Object_, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %5, align 8
%jni.fresh.mid = call ptr %jni.GetMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_getWindow____Ljava_lang_Object_, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 34
%jni.callfn = load ptr, ptr %5, align 8
%6 = getelementptr inbounds ptr, ptr %jni.ifs, i32 34
%jni.callfn = load ptr, ptr %6, align 8
%jni.ret = call ptr %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid)
%allocaN = alloca ptr, align 8
store ptr %jni.ret, ptr %allocaN, align 8
@@ -300,7 +300,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
call void @unused_jni(ptr null, ptr null)
call void @unused_jni(ptr @__sx_default_context, ptr null, ptr null)
br label %if.merge.1
if.merge.1: ; preds = %if.then.0, %entry
@@ -315,8 +315,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.3, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%call = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %call)
%call = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %call)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -326,30 +326,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -360,3 +360,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -21,39 +21,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -65,12 +65,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -82,55 +82,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -139,7 +139,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -154,27 +154,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -186,7 +186,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -208,16 +208,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -233,24 +233,24 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
define internal void @unused_jni(ptr %0, ptr %1) #0 {
define internal void @unused_jni(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%call = call ptr @sx_jni_env_tl_get()
call void @sx_jni_env_tl_set(ptr %load)
@@ -261,23 +261,23 @@ entry:
br i1 %jni.is.cached, label %jni.cont, label %jni.miss
jni.miss: ; preds = %entry
%2 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %2, align 8
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 31
%jni.GetObjectClass = load ptr, ptr %3, align 8
%jni.cls = call ptr %jni.GetObjectClass(ptr %load, ptr %loadN)
%3 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %3, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 21
%jni.NewGlobalRef = load ptr, ptr %4, align 8
%jni.global.cls = call ptr %jni.NewGlobalRef(ptr %load, ptr %jni.cls)
store ptr %jni.global.cls, ptr @SX_JNI_CLS_noop____V, align 8
%4 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %4, align 8
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 33
%jni.GetMethodID = load ptr, ptr %5, align 8
%jni.fresh.mid = call ptr %jni.GetMethodID(ptr %load, ptr %jni.global.cls, ptr @str, ptr @str.1)
store ptr %jni.fresh.mid, ptr @SX_JNI_MID_noop____V, align 8
br label %jni.cont
jni.cont: ; preds = %jni.miss, %entry
%jni.mid = phi ptr [ %jni.cached.mid, %entry ], [ %jni.fresh.mid, %jni.miss ]
%5 = getelementptr inbounds ptr, ptr %jni.ifs, i32 61
%jni.callfn = load ptr, ptr %5, align 8
%6 = getelementptr inbounds ptr, ptr %jni.ifs, i32 61
%jni.callfn = load ptr, ptr %6, align 8
call void %jni.callfn(ptr %load, ptr %loadN, ptr %jni.mid)
call void @sx_jni_env_tl_set(ptr %call)
ret void
@@ -298,7 +298,7 @@ entry:
br i1 %gload, label %if.then.0, label %if.merge.1
if.then.0: ; preds = %entry
call void @unused_jni(ptr null, ptr null)
call void @unused_jni(ptr @__sx_default_context, ptr null, ptr null)
br label %if.merge.1
if.merge.1: ; preds = %if.then.0, %entry
@@ -313,8 +313,8 @@ if.merge.1: ; preds = %if.then.0, %entry
store { ptr, i64 } { ptr @str.3, i64 0 }, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%call = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %load, { ptr, i64 } %call)
%call = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %load, { ptr, i64 } %call)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -324,30 +324,30 @@ if.merge.1: ; preds = %if.then.0, %entry
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -358,3 +358,5 @@ declare ptr @sx_jni_env_tl_get() #0
declare void @sx_jni_env_tl_set(ptr) #0
declare i64 @write(i32, ptr, i64)

View File

@@ -24,39 +24,39 @@ declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
; Function Attrs: nounwind
define internal ptr @CAllocator.alloc(ptr %0, i64 %1) #0 {
define internal ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call ptr @malloc(i64 %load)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @CAllocator.dealloc(ptr %0, ptr %1) #0 {
define internal void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %allocaN, align 8
call void @free(ptr %load)
ret void
}
; Function Attrs: nounwind
declare ptr @GPA.init() #0
declare ptr @GPA.init(ptr) #0
; Function Attrs: nounwind
define internal ptr @GPA.alloc(ptr %0, i64 %1) #0 {
define internal ptr @GPA.alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store i64 %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -68,12 +68,12 @@ entry:
}
; Function Attrs: nounwind
define internal void @GPA.dealloc(ptr %0, ptr %1) #0 {
define internal void @GPA.dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
%alloca = alloca ptr, align 8
store ptr %0, ptr %alloca, align 8
store ptr %1, ptr %alloca, align 8
%allocaN = alloca ptr, align 8
store ptr %1, ptr %allocaN, align 8
store ptr %2, ptr %allocaN, align 8
%load = load ptr, ptr %alloca, align 8
%gep = getelementptr inbounds { i64 }, ptr %load, i32 0, i32 0
%loadN = load i64, ptr %gep, align 8
@@ -85,55 +85,55 @@ entry:
}
; Function Attrs: nounwind
declare void @Arena.add_chunk(ptr, i64) #0
declare void @Arena.add_chunk(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare ptr @Arena.init(ptr, i64) #0
declare ptr @Arena.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.reset(ptr) #0
declare void @Arena.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare void @Arena.deinit(ptr) #0
declare void @Arena.deinit(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @Arena.alloc(ptr, i64) #0
declare ptr @Arena.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @Arena.dealloc(ptr, ptr) #0
declare void @Arena.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.init(ptr, i64) #0
declare ptr @BufAlloc.init(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.reset(ptr) #0
declare void @BufAlloc.reset(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @BufAlloc.alloc(ptr, i64) #0
declare ptr @BufAlloc.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @BufAlloc.dealloc(ptr, ptr) #0
declare void @BufAlloc.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.init(ptr) #0
declare ptr @TrackingAllocator.init(ptr, ptr) #0
; Function Attrs: nounwind
declare i64 @TrackingAllocator.leak_count(ptr) #0
declare i64 @TrackingAllocator.leak_count(ptr, ptr) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.report(ptr) #0
declare void @TrackingAllocator.report(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @TrackingAllocator.alloc(ptr, i64) #0
declare ptr @TrackingAllocator.alloc(ptr, ptr, i64) #0
; Function Attrs: nounwind
declare void @TrackingAllocator.dealloc(ptr, ptr) #0
declare void @TrackingAllocator.dealloc(ptr, ptr, ptr) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @cstring(i64 %0) #0 {
define internal { ptr, i64 } @cstring(ptr %0, i64 %1) #0 {
entry:
%alloca = alloca i64, align 8
store i64 %0, ptr %alloca, align 8
store i64 %1, ptr %alloca, align 8
%load = load i64, ptr %alloca, align 8
%add = add i64 %load, 1
%heap = call ptr @malloc(i64 %add)
@@ -142,7 +142,7 @@ entry:
%loadN = load ptr, ptr %allocaN, align 8
%loadN = load i64, ptr %alloca, align 8
%addN = add i64 %loadN, 1
%1 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%2 = call ptr @memset(ptr %loadN, i32 0, i64 %addN)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } undef, ptr %allocaN, align 8
%loadN = load ptr, ptr %allocaN, align 8
@@ -157,27 +157,27 @@ entry:
}
; Function Attrs: nounwind
declare ptr @int_to_string(i64) #0
declare ptr @int_to_string(ptr, i64) #0
; Function Attrs: nounwind
declare ptr @bool_to_string(i1) #0
declare ptr @bool_to_string(ptr, i1) #0
; Function Attrs: nounwind
declare ptr @float_to_string(double) #0
declare ptr @float_to_string(ptr, double) #0
; Function Attrs: nounwind
declare void @hex_group(ptr, i64, i64) #0
declare void @hex_group(ptr, ptr, i64, i64) #0
; Function Attrs: nounwind
declare ptr @int_to_hex_string(i64) #0
declare ptr @int_to_hex_string(ptr, i64) #0
; Function Attrs: nounwind
define internal { ptr, i64 } @concat({ ptr, i64 } %0, { ptr, i64 } %1) #0 {
define internal { ptr, i64 } @concat(ptr %0, { ptr, i64 } %1, { ptr, i64 } %2) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %1, ptr %allocaN, align 8
store { ptr, i64 } %2, ptr %allocaN, align 8
%load = load { ptr, i64 }, ptr %alloca, align 8
%len = extractvalue { ptr, i64 } %load, 1
%allocaN = alloca i64, align 8
@@ -189,7 +189,7 @@ entry:
%loadN = load i64, ptr %allocaN, align 8
%loadN = load i64, ptr %allocaN, align 8
%add = add i64 %loadN, %loadN
%call = call { ptr, i64 } @cstring(i64 %add)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %add)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -211,16 +211,16 @@ entry:
}
; Function Attrs: nounwind
define internal { ptr, i64 } @substr({ ptr, i64 } %0, i64 %1, i64 %2) #0 {
define internal { ptr, i64 } @substr(ptr %0, { ptr, i64 } %1, i64 %2, i64 %3) #0 {
entry:
%alloca = alloca { ptr, i64 }, align 8
store { ptr, i64 } %0, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %1, ptr %allocaN, align 8
store { ptr, i64 } %1, ptr %alloca, align 8
%allocaN = alloca i64, align 8
store i64 %2, ptr %allocaN, align 8
%allocaN = alloca i64, align 8
store i64 %3, ptr %allocaN, align 8
%load = load i64, ptr %allocaN, align 8
%call = call { ptr, i64 } @cstring(i64 %load)
%call = call { ptr, i64 } @cstring(ptr %0, i64 %load)
%allocaN = alloca { ptr, i64 }, align 8
store { ptr, i64 } %call, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
@@ -236,16 +236,16 @@ entry:
}
; Function Attrs: nounwind
declare ptr @xml_escape(ptr) #0
declare ptr @xml_escape(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @path_join(ptr) #0
declare ptr @path_join(ptr, ptr) #0
; Function Attrs: nounwind
declare ptr @any_to_string([2 x i64]) #0
declare ptr @any_to_string(ptr, [2 x i64]) #0
; Function Attrs: nounwind
declare ptr @build_format(ptr) #0
declare ptr @build_format(ptr, ptr) #0
; Function Attrs: nounwind
declare void @BuildOptions.add_link_flag(i64, ptr) #0
@@ -389,8 +389,8 @@ entry:
store { ptr, i64 } { ptr @str.1, i64 0 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%call = call { ptr, i64 } @substr({ ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat({ ptr, i64 } %loadN, { ptr, i64 } %call)
%call = call { ptr, i64 } @substr(ptr @__sx_default_context, { ptr, i64 } %loadN, i64 0, i64 3)
%callN = call { ptr, i64 } @concat(ptr @__sx_default_context, { ptr, i64 } %loadN, { ptr, i64 } %call)
store { ptr, i64 } %callN, ptr %allocaN, align 8
%loadN = load { ptr, i64 }, ptr %allocaN, align 8
%str.ptr = extractvalue { ptr, i64 } %loadN, 0
@@ -400,30 +400,30 @@ entry:
}
; Function Attrs: nounwind
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_CAllocator_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @CAllocator.alloc(ptr %0, i64 %1)
%call = call ptr @CAllocator.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_CAllocator_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @CAllocator.dealloc(ptr %0, ptr %1)
call void @CAllocator.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
; Function Attrs: nounwind
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, i64 %1) #0 {
define internal ptr @__thunk_GPA_Allocator_alloc(ptr %0, ptr %1, i64 %2) #0 {
entry:
%call = call ptr @GPA.alloc(ptr %0, i64 %1)
%call = call ptr @GPA.alloc(ptr %0, ptr %1, i64 %2)
ret ptr %call
}
; Function Attrs: nounwind
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1) #0 {
define internal void @__thunk_GPA_Allocator_dealloc(ptr %0, ptr %1, ptr %2) #0 {
entry:
call void @GPA.dealloc(ptr %0, ptr %1)
call void @GPA.dealloc(ptr %0, ptr %1, ptr %2)
ret void
}
@@ -441,3 +441,5 @@ entry:
store ptr %selN, ptr @OBJC_SELECTOR_REFERENCES_release, align 8
ret void
}

File diff suppressed because it is too large Load Diff