diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2025-12-31 15:01:08 +0000 |
|---|---|---|
| committer | gingerBill <gingerBill@users.noreply.github.com> | 2025-12-31 15:01:08 +0000 |
| commit | 3c8b1ab414f251b12fc59ce17cab074185584bc6 (patch) | |
| tree | 0d32eba065bd777f3cb449f022591331f2b5f3da | |
| parent | 6f396ac49b159e5741579d3b5bb50318e8e75851 (diff) | |
| parent | 3acb62210fcdc48d7a280a1c160ac7ff9063902f (diff) | |
Merge branch 'master' of https://github.com/odin-lang/Odin
| -rw-r--r-- | core/encoding/json/marshal.odin | 32 | ||||
| -rw-r--r-- | core/encoding/json/types.odin | 1 | ||||
| -rw-r--r-- | core/encoding/json/unmarshal.odin | 9 | ||||
| -rw-r--r-- | core/sys/wasm/js/dom.odin | 2 | ||||
| -rw-r--r-- | core/sys/wasm/js/odin.js | 81 | ||||
| -rw-r--r-- | core/unicode/letter.odin | 2 | ||||
| -rw-r--r-- | src/llvm_backend_const.cpp | 23 | ||||
| -rw-r--r-- | src/parser.cpp | 14 | ||||
| -rw-r--r-- | tests/issues/run.bat | 1 | ||||
| -rwxr-xr-x | tests/issues/run.sh | 1 | ||||
| -rw-r--r-- | tests/issues/test_issue_6068.odin | 92 | ||||
| -rw-r--r-- | vendor/wasm/WebGL/webgl.odin | 82 | ||||
| -rw-r--r-- | vendor/wasm/WebGL/webgl2.odin | 38 |
13 files changed, 354 insertions, 24 deletions
diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index e563c326a..c4e348aa8 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -122,9 +122,9 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Rune: r := a.(rune) - io.write_byte(w, '"') or_return - io.write_escaped_rune(w, r, '"', true) or_return - io.write_byte(w, '"') or_return + io.write_byte(w, '"') or_return + io.write_escaped_rune(w, r, '"', for_json = true) or_return + io.write_byte(w, '"') or_return case runtime.Type_Info_Float: switch f in a { @@ -414,6 +414,12 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: opt_write_iteration(w, opt, first_iteration) or_return first_iteration = false + + if opt.pretty { + comment := reflect.struct_tag_get(reflect.Struct_Tag(info.tags[i]), "jsoncomment") + opt_write_comment(w, opt, &comment) or_return + } + if json_name != "" { opt_write_key(w, opt, json_name) or_return } else { @@ -533,6 +539,26 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: return } +// Newlines are split into multiple comment lines +opt_write_comment :: proc(w: io.Writer, opt: ^Marshal_Options, comment: ^string) -> (err: io.Error) { + if comment^ == "" { + return nil + } + + switch opt.spec { + case .JSON5, .MJSON: + for line in strings.split_iterator(comment, "\n") { + io.write_string(w, "// ") or_return + io.write_string(w, line) or_return + io.write_rune(w, '\n') or_return + opt_write_indentation(w, opt) or_return + } + case .JSON: return nil + } + + return nil +} + // write key as quoted string or with optional quotes in mjson opt_write_key :: proc(w: io.Writer, opt: ^Marshal_Options, name: string) -> (err: io.Error) { switch opt.spec { diff --git a/core/encoding/json/types.odin b/core/encoding/json/types.odin index 1da17a0db..77cc7db85 100644 --- a/core/encoding/json/types.odin +++ b/core/encoding/json/types.odin @@ -76,6 +76,7 @@ Error :: enum { Invalid_Number, String_Not_Terminated, Invalid_String, + Invalid_Rune, // Parsing Errors diff --git a/core/encoding/json/unmarshal.odin b/core/encoding/json/unmarshal.odin index 3cdc6429d..58365b684 100644 --- a/core/encoding/json/unmarshal.odin +++ b/core/encoding/json/unmarshal.odin @@ -225,6 +225,15 @@ unmarshal_string_token :: proc(p: ^Parser, val: any, token: Token, ti: ^reflect. } ok = true return + case rune: + for rne, i in str { + if i > 0 { + dst = {} + return false, .Invalid_Rune + } + dst = rne + } + return true, nil } #partial switch variant in ti.variant { diff --git a/core/sys/wasm/js/dom.odin b/core/sys/wasm/js/dom.odin index a4f8d7687..6dd9dbf45 100644 --- a/core/sys/wasm/js/dom.odin +++ b/core/sys/wasm/js/dom.odin @@ -22,6 +22,8 @@ foreign dom_lib { window_set_scroll :: proc(x, y: f64) --- set_element_style :: proc(id: string, key: string, value: string) --- + + set_document_title :: proc(title: string) --- } get_element_value_string :: proc "contextless" (id: string, buf: []byte) -> string { diff --git a/core/sys/wasm/js/odin.js b/core/sys/wasm/js/odin.js index ef203e24d..19ac3093e 100644 --- a/core/sys/wasm/js/odin.js +++ b/core/sys/wasm/js/odin.js @@ -616,6 +616,9 @@ class WebGLInterface { FramebufferTexture2D: (target, attachment, textarget, texture, level) => { this.ctx.framebufferTexture2D(target, attachment, textarget, this.textures[texture], level); }, + CheckFramebufferStatus: (target) => { + return this.ctx.checkFramebufferStatus(target) + }, FrontFace: (mode) => { this.ctx.frontFace(mode); }, @@ -625,6 +628,47 @@ class WebGLInterface { this.ctx.generateMipmap(target); }, + GetActiveAttrib: (program, index, size_ptr, type_ptr, name_buf_ptr, name_buf_len, name_len_ptr) => { + const info = this.ctx.getActiveAttrib(this.programs[program], index); + + if (size_ptr) { + this.mem.storeInt(size_ptr, info.size); + } + + if (type_ptr) { + this.mem.storeI32(type_ptr, info.type); + } + + if (name_buf_ptr && name_buf_len > 0) { + let n = Math.min(name_buf_len, info.name.length); + let name = info.name.substring(0, n); + this.mem.loadBytes(name_buf_ptr, name_buf_len).set(new TextEncoder().encode(name)); + this.mem.storeInt(name_len_ptr, n); + } else if (name_len_ptr) { + this.mem.storeInt(name_len_ptr, info.name.length); + } + }, + + GetActiveUniform: (program, index, size_ptr, type_ptr, name_buf_ptr, name_buf_len, name_len_ptr) => { + let info = this.ctx.getActiveUniform(this.programs[program], index); + + if (size_ptr) { + this.mem.storeInt(size_ptr, info.size); + } + + if (type_ptr) { + this.mem.storeI32(type_ptr, info.type); + } + + if (name_buf_ptr && name_buf_len > 0) { + let n = Math.min(name_buf_len, info.name.length); + let name = info.name.substring(0, n); + this.mem.loadBytes(name_buf_ptr, name_buf_len).set(new TextEncoder().encode(name)); + this.mem.storeInt(name_len_ptr, n); + } else if (name_len_ptr) { + this.mem.storeInt(name_len_ptr, info.name.length); + } + }, GetAttribLocation: (program, name_ptr, name_len) => { let name = this.mem.loadString(name_ptr, name_len); @@ -1260,15 +1304,34 @@ class WebGLInterface { this.assertWebGL2(); return this.ctx.getUniformBlockIndex(this.programs[program], this.mem.loadString(uniformBlockName_ptr, uniformBlockName_len)); }, - // any getActiveUniformBlockParameter(WebGLProgram program, GLuint uniformBlockIndex, GLenum pname); - GetActiveUniformBlockName: (program, uniformBlockIndex, buf_ptr, buf_len, length_ptr) => { + GetActiveUniformBlockName: (program, uniformBlockIndex, name_buf_ptr, name_buf_len, name_length_ptr) => { this.assertWebGL2(); let name = this.ctx.getActiveUniformBlockName(this.programs[program], uniformBlockIndex); - let n = Math.min(buf_len, name.length); - name = name.substring(0, n); - this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder().encode(name)) - this.mem.storeInt(length_ptr, n); + if (name_buf_ptr && name_buf_len > 0) { + let n = Math.min(name_buf_len, name.length); + name = name.substring(0, n); + this.mem.loadBytes(name_buf_ptr, name_buf_len).set(new TextEncoder().encode(name)); + this.mem.storeInt(name_length_ptr, n); + } else if (name_length_ptr) { + this.mem.storeInt(name_length_ptr, name.length); + } + }, + GetActiveUniforms: (program, uniformIndices_ptr, uniformIndices_len, pname, res_ptr) => { + this.assertWebGL2(); + let indices = this.mem.loadU32Array(uniformIndices_ptr, uniformIndices_len); + this.ctx.getActiveUniforms(this.programs[program], indices, pname) + this.mem.loadI32Array(res_ptr, indices.length).set(indices) + }, + GetActiveUniformBlockParameter: (program, uniformBlockIndex, pname, params_ptr) => { + this.assertWebGL2(); + let res = this.ctx.getActiveUniformBlockParameter(this.programs[program], uniformBlockIndex, pname); + + if (res instanceof Uint32Array) { // for pname GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES + this.mem.loadU32Array(params_ptr, res.length).set(res) + } else { + this.mem.storeI32(params_ptr, res) + } }, UniformBlockBinding: (program, uniformBlockIndex, uniformBlockBinding) => { this.assertWebGL2(); @@ -1840,6 +1903,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory) { return false; }, + // Writes a struct of type `Gamepad_State`, see `core/sys/wasm/js/events.odin` get_gamepad_state: (gamepad_id, ep) => { let index = gamepad_id; let gps = navigator.getGamepads(); @@ -1986,6 +2050,11 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement, memory) { } }, + set_document_title: (title_ptr, title_len) => { + let title = wasmMemoryInterface.loadString(title_ptr, title_len); + document.title = title; + }, + get_element_key_f64: (id_ptr, id_len, key_ptr, key_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); let key = wasmMemoryInterface.loadString(key_ptr, key_len); diff --git a/core/unicode/letter.odin b/core/unicode/letter.odin index a1024dd6c..5191dd900 100644 --- a/core/unicode/letter.odin +++ b/core/unicode/letter.odin @@ -2,7 +2,7 @@ package unicode import "base:runtime" -MAX_RUNE :: '\U00010fff' // Maximum valid unicode code point +MAX_RUNE :: '\U0010ffff' // Maximum valid unicode code point REPLACEMENT_CHAR :: '\ufffd' // Represented an invalid code point MAX_ASCII :: '\u007f' // Maximum ASCII value MAX_LATIN1 :: '\u00ff' // Maximum Latin-1 value diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 22e124792..8ce2137ab 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -498,6 +498,13 @@ gb_internal LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, Bi if (big_int_is_zero(a)) { return LLVMConstNull(lb_type(m, original_type)); } + + BigInt val = {}; + big_int_init(&val, a); + + if (big_int_is_neg(&val)) { + mp_incr(&val); + } size_t sz = cast(size_t)type_size_of(original_type); u64 rop64[4] = {}; // 2 u64 is the maximum we will ever need, so doubling it will be fine :P @@ -509,7 +516,7 @@ gb_internal LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, Bi size_t nails = 0; mp_endian endian = MP_LITTLE_ENDIAN; - max_count = mp_pack_count(a, nails, size); + max_count = mp_pack_count(&val, nails, size); if (sz < max_count) { debug_print_big_int(a); gb_printf_err("%s -> %tu\n", type_to_string(original_type), sz); @@ -520,7 +527,7 @@ gb_internal LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, Bi mp_err err = mp_pack(rop, sz, &written, MP_LSB_FIRST, size, endian, nails, - a); + &val); GB_ASSERT(err == MP_OKAY); if (!is_type_endian_little(original_type)) { @@ -531,12 +538,18 @@ gb_internal LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, Bi } } + if (big_int_is_neg(a)) { + // sizeof instead of sz for sign extend to work properly + for (size_t i = 0; i < sizeof rop64; i++) { + rop[i] = ~rop[i]; + } + } + + big_int_dealloc(&val); + GB_ASSERT(!is_type_array(original_type)); LLVMValueRef value = LLVMConstIntOfArbitraryPrecision(lb_type(m, original_type), cast(unsigned)((sz+7)/8), cast(u64 *)rop); - if (big_int_is_neg(a)) { - value = LLVMConstNeg(value); - } return value; } diff --git a/src/parser.cpp b/src/parser.cpp index b2ff55396..823021e04 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2183,7 +2183,7 @@ gb_internal Ast *parse_force_inlining_operand(AstFile *f, Token token) { return expr; } if (e->kind != Ast_ProcLit && e->kind != Ast_CallExpr) { - syntax_error(expr, "%.*s must be followed by a procedure literal or call, got %.*s", LIT(token.string), LIT(ast_strings[expr->kind])); + syntax_error(expr, "%.*s must be followed by a procedure literal or call, got %.*s", LIT(token.string), LIT(ast_strings[e->kind])); return ast_bad_expr(f, token, f->curr_token); } ProcInlining pi = ProcInlining_none; @@ -2197,17 +2197,17 @@ gb_internal Ast *parse_force_inlining_operand(AstFile *f, Token token) { if (pi != ProcInlining_none) { if (e->kind == Ast_ProcLit) { - if (expr->ProcLit.inlining != ProcInlining_none && - expr->ProcLit.inlining != pi) { + if (e->ProcLit.inlining != ProcInlining_none && + e->ProcLit.inlining != pi) { syntax_error(expr, "Cannot apply both '#force_inline' and '#force_no_inline' to a procedure literal"); } - expr->ProcLit.inlining = pi; + e->ProcLit.inlining = pi; } else if (e->kind == Ast_CallExpr) { - if (expr->CallExpr.inlining != ProcInlining_none && - expr->CallExpr.inlining != pi) { + if (e->CallExpr.inlining != ProcInlining_none && + e->CallExpr.inlining != pi) { syntax_error(expr, "Cannot apply both '#force_inline' and '#force_no_inline' to a procedure call"); } - expr->CallExpr.inlining = pi; + e->CallExpr.inlining = pi; } } diff --git a/tests/issues/run.bat b/tests/issues/run.bat index bbd7cbc90..0ceaf554c 100644 --- a/tests/issues/run.bat +++ b/tests/issues/run.bat @@ -26,6 +26,7 @@ set COMMON=-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused ..\..\..\odin build ..\test_issue_5097-2.odin %COMMON% || exit /b ..\..\..\odin build ..\test_issue_5265.odin %COMMON% || exit /b ..\..\..\odin test ..\test_issue_5699.odin %COMMON% || exit /b +..\..\..\odin test ..\test_issue_6068.odin %COMMON% || exit /b @echo off diff --git a/tests/issues/run.sh b/tests/issues/run.sh index a9a4bb88d..ce02ba20a 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -33,6 +33,7 @@ $ODIN build ../test_issue_5097.odin $COMMON $ODIN build ../test_issue_5097-2.odin $COMMON $ODIN build ../test_issue_5265.odin $COMMON $ODIN test ../test_issue_5699.odin $COMMON +$ODIN test ../test_issue_6068.odin $COMMON set +x diff --git a/tests/issues/test_issue_6068.odin b/tests/issues/test_issue_6068.odin new file mode 100644 index 000000000..011c95442 --- /dev/null +++ b/tests/issues/test_issue_6068.odin @@ -0,0 +1,92 @@ +// Tests issue #6068 https://github.com/odin-lang/Odin/issues/6068 +package test_issues + +import "core:testing" + +@test +test_issue_6068 :: proc(t: ^testing.T) { + { + check_be : i128be = -1 + check_le : i128le = -1 + value := -1 + reverse := i128be(value) + + // test variable + testing.expect(t, i128be(value) == check_be) + testing.expect(t, i128be(-1) == check_be) + testing.expect(t, cast(i128be)value == check_be) + testing.expect(t, cast(i128be)-1 == check_be) + testing.expect(t, i128be(int(-1)) == check_be) + testing.expect(t, cast(i128be)int(-1) == check_be) + testing.expect(t, i128le(value) == check_le) + testing.expect(t, i128le(-1) == check_le) + testing.expect(t, cast(i128le)value == check_le) + testing.expect(t, cast(i128le)-1 == check_le) + testing.expect(t, i128le(int(-1)) == check_le) + testing.expect(t, cast(i128le)int(-1) == check_le) + testing.expect(t, i128le(reverse) == check_le) + testing.expect(t, cast(i128le)reverse == check_le) + + // test literal + testing.expect(t, i128be(value) == -1) + testing.expect(t, i128be(-1) == -1) + testing.expect(t, cast(i128be)value == -1) + testing.expect(t, cast(i128be)-1 == -1) + testing.expect(t, i128be(int(-1)) == -1) + testing.expect(t, cast(i128be)int(-1) == -1) + testing.expect(t, i128le(value) == -1) + testing.expect(t, i128le(-1) == -1) + testing.expect(t, cast(i128le)value == -1) + testing.expect(t, cast(i128le)-1 == -1) + testing.expect(t, i128le(int(-1)) == -1) + testing.expect(t, cast(i128le)int(-1) == -1) + testing.expect(t, i128le(reverse) == -1) + testing.expect(t, cast(i128le)reverse == -1) + } + + // NOTE(ske): [llvm_backend_const.cpp:lb_big_int_to_llvm] + // floats behaved wonky when I tested because I forgot to sign extend whole + // rop so I added more tests here to be safe + { + check_be : f64be = -1.234 + check_le : f64le = -1.234 + value : f64 = -1.234 + reverse := f64be(value) + + // test variable + testing.expect(t, f64be(value) == check_be) + testing.expect(t, f64be(-1.234) == check_be) + testing.expect(t, cast(f64be)value == check_be) + testing.expect(t, cast(f64be)-1.234 == check_be) + testing.expect(t, f64be(int(-1.234)) == check_be) + testing.expect(t, cast(f64be)int(-1.234) == check_be) + testing.expect(t, f64le(value) == check_le) + testing.expect(t, f64le(-1.234) == check_le) + testing.expect(t, cast(f64le)value == check_le) + testing.expect(t, cast(f64le)-1.234 == check_le) + testing.expect(t, f64le(int(-1.234)) == check_le) + testing.expect(t, cast(f64le)int(-1.234) == check_le) + testing.expect(t, f64le(reverse) == check_le) + testing.expect(t, cast(f64le)reverse == check_le) + + // test literal + testing.expect(t, f64be(value) == -1.234) + testing.expect(t, f64be(-1.234) == -1.234) + testing.expect(t, cast(f64be)value == -1.234) + testing.expect(t, cast(f64be)-1.234 == -1.234) + testing.expect(t, f64be(int(-1.234)) == -1.234) + testing.expect(t, cast(f64be)int(-1.234) == -1.234) + testing.expect(t, f64le(value) == -1.234) + testing.expect(t, f64le(-1.234) == -1.234) + testing.expect(t, cast(f64le)value == -1.234) + testing.expect(t, cast(f64le)-1.234 == -1.234) + testing.expect(t, f64le(int(-1.234)) == -1.234) + testing.expect(t, cast(f64le)int(-1.234) == -1.234) + testing.expect(t, f64le(reverse) == -1.234) + testing.expect(t, cast(f64le)reverse == -1.234) + } + + testing.expect(t, i64be(-1) + i64be(1) == 0) + testing.expect(t, i64le(-1) + i64le(i64be(1)) == 0) + testing.expect(t, i64be(-7) * i64be(7) == -49) +} diff --git a/vendor/wasm/WebGL/webgl.odin b/vendor/wasm/WebGL/webgl.odin index 5616f3660..d607ec743 100644 --- a/vendor/wasm/WebGL/webgl.odin +++ b/vendor/wasm/WebGL/webgl.odin @@ -3,6 +3,7 @@ package webgl foreign import "webgl" import glm "core:math/linalg/glsl" +import "base:runtime" Enum :: distinct u32 @@ -25,6 +26,12 @@ ContextAttribute :: enum u32 { } ContextAttributes :: distinct bit_set[ContextAttribute; u32] +ActiveInfo :: struct { + size: int, + type: Enum, + name: string, +} + DEFAULT_CONTEXT_ATTRIBUTES :: ContextAttributes{} @(default_calling_convention="contextless") @@ -106,6 +113,7 @@ foreign webgl { Flush :: proc() --- FramebufferRenderbuffer :: proc(target, attachment, renderbufertarget: Enum, renderbuffer: Renderbuffer) --- FramebufferTexture2D :: proc(target, attachment, textarget: Enum, texture: Texture, level: i32) --- + CheckFramebufferStatus :: proc(target: Enum) -> Enum --- FrontFace :: proc(mode: Enum) --- GenerateMipmap :: proc(target: Enum) --- @@ -260,7 +268,6 @@ UniformMatrix4fv :: proc "contextless" (location: i32, m: glm.mat4) { value := transmute([4*4]f32)m _UniformMatrix4fv(location, &value[0]) } - GetShaderiv :: proc "contextless" (shader: Shader, pname: Enum) -> (p: i32) { foreign webgl { @(link_name="GetShaderiv") @@ -270,6 +277,79 @@ GetShaderiv :: proc "contextless" (shader: Shader, pname: Enum) -> (p: i32) { return } +GetActiveAttribBuf :: proc "contextless" (program: Program, index: u32, name_buf: []byte) -> (info: ActiveInfo) { + foreign webgl { + @(link_name="GetActiveAttrib") + _GetActiveAttrib :: proc "contextless" (shader: Program, index: u32, size: ^int, type: ^Enum, name_buf: []byte, name_len: ^int) --- + } + name_len: int + _GetActiveAttrib(program, index, &info.size, &info.type, name_buf, &name_len) + info.name = string(name_buf[:name_len]) + return +} + +GetActiveAttribAlloc :: proc(program: Program, index: u32, allocator: runtime.Allocator, loc := #caller_location) -> (info: ActiveInfo) { + foreign webgl { + @(link_name="GetActiveAttrib") + _GetActiveAttrib :: proc "contextless" (shader: Program, index: u32, size: ^int, type: ^Enum, name_buf: []byte, name_len: ^int) --- + } + + name_len: int + + // Passing {} to the buf but giving it a name_len ptr will write the needed len into that int + _GetActiveAttrib(program, index, &info.size, &info.type, {}, &name_len) + + if name_len > 0 { + name_buf := make([]byte, name_len, allocator, loc) + _GetActiveAttrib(program, index, &info.size, &info.type, name_buf, &name_len) + assert(name_len == len(name_buf)) + info.name = string(name_buf[:name_len]) + } + + return +} + +GetActiveAttrib :: proc { + GetActiveAttribBuf, + GetActiveAttribAlloc, +} + +GetActiveUniformBuf :: proc "contextless" (program: Program, index: u32, name_buf: []byte) -> (info: ActiveInfo) { + foreign webgl { + @(link_name="GetActiveUniform") + _GetActiveUniform :: proc "contextless" (shader: Program, index: u32, size: ^int, type: ^Enum, name_buf: []byte, name_len: ^int) --- + } + name_len: int + _GetActiveUniform(program, index, &info.size, &info.type, name_buf, &name_len) + info.name = string(name_buf[:name_len]) + return +} + +GetActiveUniformAlloc :: proc(program: Program, index: u32, allocator: runtime.Allocator, loc := #caller_location) -> (info: ActiveInfo) { + foreign webgl { + @(link_name="GetActiveUniform") + _GetActiveUniform :: proc "contextless" (shader: Program, index: u32, size: ^int, type: ^Enum, name_buf: []byte, name_len: ^int) --- + } + + name_len: int + + // Passing {} to the buf but giving it a name_len ptr will write the needed len into that int + _GetActiveUniform(program, index, &info.size, &info.type, {}, &name_len) + + if name_len > 0 { + name_buf := make([]byte, name_len, allocator, loc) + _GetActiveUniform(program, index, &info.size, &info.type, name_buf, &name_len) + assert(name_len == len(name_buf)) + info.name = string(name_buf[:name_len]) + } + + return +} + +GetActiveUniform :: proc { + GetActiveUniformBuf, + GetActiveUniformAlloc, +} GetProgramInfoLog :: proc "contextless" (program: Program, buf: []byte) -> string { foreign webgl { diff --git a/vendor/wasm/WebGL/webgl2.odin b/vendor/wasm/WebGL/webgl2.odin index 66a739303..1e36fd0fd 100644 --- a/vendor/wasm/WebGL/webgl2.odin +++ b/vendor/wasm/WebGL/webgl2.odin @@ -3,6 +3,7 @@ package webgl foreign import "webgl2" import "base:intrinsics" +import "base:runtime" import glm "core:math/linalg/glsl" Query :: distinct u32 @@ -103,14 +104,21 @@ foreign webgl2 { GetUniformBlockIndex :: proc(program: Program, uniformBlockName: string) -> i32 --- UniformBlockBinding :: proc(program: Program, uniformBlockIndex: i32, uniformBlockBinding: i32) --- + // if `pname` is `UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES` then an array will be written at + // `params`, in that case the length `params` need to have is given first querying using `pname` + // `UNIFORM_BLOCK_ACTIVE_UNIFORMS`. + GetActiveUniformBlockParameter :: proc(program: Program, uniformBlockIndex: i32, pname: Enum, params: [^]i32) --- + GetActiveUniforms :: proc(program: Program, uniformIndices: []u32, pname: Enum, res: [^]i32) --- + CreateVertexArray :: proc() -> VertexArrayObject --- DeleteVertexArray :: proc(vertexArray: VertexArrayObject) --- IsVertexArray :: proc(vertexArray: VertexArrayObject) -> bool --- BindVertexArray :: proc(vertexArray: VertexArrayObject) --- } -GetActiveUniformBlockName :: proc(program: Program, uniformBlockIndex: i32, buf: []byte) -> string { +GetActiveUniformBlockNameBuf :: proc(program: Program, uniformBlockIndex: i32, buf: []byte) -> string { foreign webgl2 { + @(link_name="GetActiveUniformBlockName") _GetActiveUniformBlockName :: proc "contextless" (program: Program, uniformBlockIndex: i32, buf: []byte, length: ^int) --- } n: int @@ -118,6 +126,28 @@ GetActiveUniformBlockName :: proc(program: Program, uniformBlockIndex: i32, buf: return string(buf[:n]) } +GetActiveUniformBlockNameAlloc :: proc(program: Program, uniformBlockIndex: i32, allocator: runtime.Allocator, loc := #caller_location) -> string { + foreign webgl2 { + @(link_name="GetActiveUniformBlockName") + _GetActiveUniformBlockName :: proc "contextless" (program: Program, uniformBlockIndex: i32, buf: []byte, length: ^int) --- + } + n: int + _GetActiveUniformBlockName(program, uniformBlockIndex, {}, &n) + + if n > 0 { + buf := make([]byte, n, allocator, loc) + _GetActiveUniformBlockName(program, uniformBlockIndex, buf, &n) + assert(n == len(buf)) + return string(buf[:n]) + } + + return "" +} + +GetActiveUniformBlockName :: proc { + GetActiveUniformBlockNameBuf, + GetActiveUniformBlockNameAlloc, +} Uniform1uiv :: proc "contextless" (location: i32, v: u32) { Uniform1ui(location, v) @@ -134,6 +164,7 @@ Uniform4uiv :: proc "contextless" (location: i32, v: glm.uvec4) { UniformMatrix3x2fv :: proc "contextless" (location: i32, m: glm.mat3x2) { foreign webgl2 { + @(link_name="UniformMatrix3x2fv") _UniformMatrix3x2fv :: proc "contextless" (location: i32, addr: [^]f32) --- } array := intrinsics.matrix_flatten(m) @@ -141,6 +172,7 @@ UniformMatrix3x2fv :: proc "contextless" (location: i32, m: glm.mat3x2) { } UniformMatrix4x2fv :: proc "contextless" (location: i32, m: glm.mat4x2) { foreign webgl2 { + @(link_name="UniformMatrix4x2fv") _UniformMatrix4x2fv :: proc "contextless" (location: i32, addr: [^]f32) --- } array := intrinsics.matrix_flatten(m) @@ -148,6 +180,7 @@ UniformMatrix4x2fv :: proc "contextless" (location: i32, m: glm.mat4x2) { } UniformMatrix2x3fv :: proc "contextless" (location: i32, m: glm.mat2x3) { foreign webgl2 { + @(link_name="UniformMatrix2x3fv") _UniformMatrix2x3fv :: proc "contextless" (location: i32, addr: [^]f32) --- } array := intrinsics.matrix_flatten(m) @@ -155,6 +188,7 @@ UniformMatrix2x3fv :: proc "contextless" (location: i32, m: glm.mat2x3) { } UniformMatrix4x3fv :: proc "contextless" (location: i32, m: glm.mat4x3) { foreign webgl2 { + @(link_name="UniformMatrix4x3fv") _UniformMatrix4x3fv :: proc "contextless" (location: i32, addr: [^]f32) --- } array := intrinsics.matrix_flatten(m) @@ -162,6 +196,7 @@ UniformMatrix4x3fv :: proc "contextless" (location: i32, m: glm.mat4x3) { } UniformMatrix2x4fv :: proc "contextless" (location: i32, m: glm.mat2x4) { foreign webgl2 { + @(link_name="UniformMatrix2x4fv") _UniformMatrix2x4fv :: proc "contextless" (location: i32, addr: [^]f32) --- } array := intrinsics.matrix_flatten(m) @@ -169,6 +204,7 @@ UniformMatrix2x4fv :: proc "contextless" (location: i32, m: glm.mat2x4) { } UniformMatrix3x4fv :: proc "contextless" (location: i32, m: glm.mat3x4) { foreign webgl2 { + @(link_name="UniformMatrix3x4fv") _UniformMatrix3x4fv :: proc "contextless" (location: i32, addr: [^]f32) --- } array := intrinsics.matrix_flatten(m) |