konpeito 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/konpeito/codegen/cruby_backend.rb +5 -2
- data/lib/konpeito/codegen/inliner.rb +106 -0
- data/lib/konpeito/hir/builder.rb +5 -2
- data/lib/konpeito/stdlib/json/yyjson_wrapper.c +60 -0
- data/lib/konpeito/version.rb +1 -1
- data/scripts/setup_vendor.sh +33 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85de87c8abf1bbf3ecaf6303ba4fd875f16016099a38734c55c108f123fa4086
|
|
4
|
+
data.tar.gz: 843f4b6d722d68526d031734c035c9126c520d9869a2488259dbf39ce1eade84
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eaf22b341a9135b2d81fcda350790330a78f2da9255771833676047086fbcd861919295f8cf7f4967f380cc62c8ea882499cd6b89a863b86bbd1c53e6e6f2b9e
|
|
7
|
+
data.tar.gz: ab456db3432eca45ff8b658b80c07d38cdbec33c1e4cd6e379d59dbb0cf8f3384b6f715b3bac61f7d120dfb25e479fe86b65dc4c44ad5c7e86ab18703ff6e6a9
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@ All notable changes to Konpeito will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2026-02-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Inliner: keyword argument mapping for correct inlining of functions with keyword params
|
|
12
|
+
- Inliner: ProcNew/BlockDef deep cloning with proper captured variable renaming
|
|
13
|
+
- Vendor setup script (`scripts/setup_vendor.sh`) to download yyjson source files
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- HIR builder: save/restore `@current_block` in NativeHashEach to emit into correct basic block
|
|
17
|
+
- Inliner: ProcCall handler for proc_value and args renaming during inlining
|
|
18
|
+
- JSON stdlib: add tracked `yyjson_wrapper.c` providing non-inline wrappers for LLVM-generated code (fixes SEGV in `parse_as`/`parse_array_as` tests)
|
|
19
|
+
- CRuby backend: reference yyjson wrapper from tracked source location instead of vendor directory
|
|
20
|
+
|
|
8
21
|
## [0.1.3] - 2026-02-18
|
|
9
22
|
|
|
10
23
|
### Fixed
|
|
@@ -108,6 +121,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
108
121
|
- `%a{extern}` - external C struct wrappers
|
|
109
122
|
- `%a{simd}` - SIMD vectorization
|
|
110
123
|
|
|
124
|
+
[0.2.0]: https://github.com/i2y/konpeito/compare/v0.1.3...v0.2.0
|
|
111
125
|
[0.1.3]: https://github.com/i2y/konpeito/compare/v0.1.2...v0.1.3
|
|
112
126
|
[0.1.2]: https://github.com/i2y/konpeito/compare/v0.1.1...v0.1.2
|
|
113
127
|
[0.1.1]: https://github.com/i2y/konpeito/compare/v0.1.0...v0.1.1
|
|
@@ -893,7 +893,10 @@ module Konpeito
|
|
|
893
893
|
yyjson_dir = File.expand_path("../../../vendor/yyjson", __dir__)
|
|
894
894
|
yyjson_c = File.join(yyjson_dir, "yyjson.c")
|
|
895
895
|
yyjson_obj = File.join(yyjson_dir, "yyjson.o")
|
|
896
|
-
|
|
896
|
+
|
|
897
|
+
# Wrapper source is tracked in repo alongside JSON stdlib
|
|
898
|
+
json_stdlib_dir = File.expand_path("../stdlib/json", __dir__)
|
|
899
|
+
wrapper_c = File.join(json_stdlib_dir, "yyjson_wrapper.c")
|
|
897
900
|
wrapper_obj = File.join(yyjson_dir, "yyjson_wrapper.o")
|
|
898
901
|
|
|
899
902
|
return [] unless File.exist?(yyjson_c) && File.exist?(wrapper_c)
|
|
@@ -906,7 +909,7 @@ module Konpeito
|
|
|
906
909
|
system(*cmd) or return []
|
|
907
910
|
end
|
|
908
911
|
|
|
909
|
-
# Compile wrapper
|
|
912
|
+
# Compile wrapper (needs yyjson.h from vendor dir)
|
|
910
913
|
unless File.exist?(wrapper_obj) && File.mtime(wrapper_obj) > File.mtime(wrapper_c)
|
|
911
914
|
cmd = [cc, "-c", "-O3", "-fPIC", "-I#{yyjson_dir}", "-o", wrapper_obj, wrapper_c]
|
|
912
915
|
system(*cmd) or return []
|
|
@@ -178,6 +178,17 @@ module Konpeito
|
|
|
178
178
|
param_map[param.name] = call_inst.args[i]
|
|
179
179
|
end
|
|
180
180
|
end
|
|
181
|
+
# Also map keyword arguments by name
|
|
182
|
+
if call_inst.respond_to?(:keyword_args) && call_inst.has_keyword_args?
|
|
183
|
+
call_inst.keyword_args.each do |kw_name, kw_value|
|
|
184
|
+
# Find the callee param with matching name
|
|
185
|
+
callee.params.each do |param|
|
|
186
|
+
if param.name.to_s == kw_name.to_s
|
|
187
|
+
param_map[param.name] = kw_value
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
181
192
|
|
|
182
193
|
# Clone and transform instructions from callee
|
|
183
194
|
result_instructions = []
|
|
@@ -438,6 +449,17 @@ module Konpeito
|
|
|
438
449
|
new_args = inst.args.map { |a| transform_value(a, prefix, param_map) }
|
|
439
450
|
HIR::SuperCall.new(args: new_args, type: inst.type, result_var: new_result)
|
|
440
451
|
|
|
452
|
+
when HIR::ProcNew
|
|
453
|
+
new_result = inst.result_var ? prefix + inst.result_var : nil
|
|
454
|
+
new_block_def = clone_block_def(inst.block_def, prefix, param_map)
|
|
455
|
+
HIR::ProcNew.new(block_def: new_block_def, result_var: new_result)
|
|
456
|
+
|
|
457
|
+
when HIR::ProcCall
|
|
458
|
+
new_result = inst.result_var ? prefix + inst.result_var : nil
|
|
459
|
+
new_proc = transform_value(inst.proc_value, prefix, param_map)
|
|
460
|
+
new_args = inst.args.map { |a| transform_value(a, prefix, param_map) }
|
|
461
|
+
HIR::ProcCall.new(proc_value: new_proc, args: new_args, type: inst.type, result_var: new_result)
|
|
462
|
+
|
|
441
463
|
else
|
|
442
464
|
# For other instructions, just return as-is with renamed result
|
|
443
465
|
inst
|
|
@@ -481,6 +503,90 @@ module Konpeito
|
|
|
481
503
|
value
|
|
482
504
|
end
|
|
483
505
|
end
|
|
506
|
+
|
|
507
|
+
# Deep-clone a BlockDef, renaming captured (non-block-local) variables.
|
|
508
|
+
# Block parameters are NOT renamed (they are local to the closure).
|
|
509
|
+
def clone_block_def(block_def, prefix, param_map)
|
|
510
|
+
return block_def unless block_def
|
|
511
|
+
|
|
512
|
+
block_param_names = Set.new(block_def.params.map { |p| p.name.to_s })
|
|
513
|
+
|
|
514
|
+
new_body = block_def.body.map do |bb|
|
|
515
|
+
if bb.respond_to?(:instructions)
|
|
516
|
+
new_bb = HIR::BasicBlock.new(label: bb.label)
|
|
517
|
+
bb.instructions.each do |bi|
|
|
518
|
+
new_inst = clone_block_instruction(bi, prefix, param_map, block_param_names)
|
|
519
|
+
new_bb.add_instruction(new_inst) if new_inst
|
|
520
|
+
end
|
|
521
|
+
new_bb.set_terminator(bb.terminator) if bb.terminator
|
|
522
|
+
new_bb
|
|
523
|
+
else
|
|
524
|
+
clone_block_instruction(bb, prefix, param_map, block_param_names)
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
HIR::BlockDef.new(
|
|
529
|
+
params: block_def.params,
|
|
530
|
+
body: new_body,
|
|
531
|
+
captures: block_def.captures,
|
|
532
|
+
is_lambda: block_def.is_lambda
|
|
533
|
+
)
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
# Clone a single instruction inside a block body, renaming captured vars.
|
|
537
|
+
def clone_block_instruction(inst, prefix, param_map, block_param_names)
|
|
538
|
+
case inst
|
|
539
|
+
when HIR::LoadLocal
|
|
540
|
+
var_name = inst.var.name.to_s
|
|
541
|
+
if block_param_names.include?(var_name)
|
|
542
|
+
# Block-local parameter: don't rename
|
|
543
|
+
inst
|
|
544
|
+
else
|
|
545
|
+
# Captured variable: rename with prefix
|
|
546
|
+
new_var = HIR::LocalVar.new(
|
|
547
|
+
name: prefix + var_name,
|
|
548
|
+
type: inst.var.type
|
|
549
|
+
)
|
|
550
|
+
HIR::LoadLocal.new(var: new_var, type: inst.type, result_var: inst.result_var)
|
|
551
|
+
end
|
|
552
|
+
when HIR::StoreLocal
|
|
553
|
+
var_name = inst.var.name.to_s
|
|
554
|
+
new_value = clone_block_value(inst.value, prefix, param_map, block_param_names)
|
|
555
|
+
if block_param_names.include?(var_name)
|
|
556
|
+
HIR::StoreLocal.new(var: inst.var, value: new_value, type: inst.type)
|
|
557
|
+
else
|
|
558
|
+
new_var = HIR::LocalVar.new(name: prefix + var_name, type: inst.var.type)
|
|
559
|
+
HIR::StoreLocal.new(var: new_var, value: new_value, type: inst.type)
|
|
560
|
+
end
|
|
561
|
+
when HIR::Call
|
|
562
|
+
new_receiver = clone_block_value(inst.receiver, prefix, param_map, block_param_names)
|
|
563
|
+
new_args = inst.args.map { |a| clone_block_value(a, prefix, param_map, block_param_names) }
|
|
564
|
+
HIR::Call.new(
|
|
565
|
+
receiver: new_receiver, method_name: inst.method_name,
|
|
566
|
+
args: new_args, block: inst.block,
|
|
567
|
+
type: inst.type, result_var: inst.result_var
|
|
568
|
+
)
|
|
569
|
+
else
|
|
570
|
+
# Other instructions: return as-is (literals, etc.)
|
|
571
|
+
inst
|
|
572
|
+
end
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
# Clone a value reference inside a block, renaming captured variables.
|
|
576
|
+
def clone_block_value(value, prefix, param_map, block_param_names)
|
|
577
|
+
case value
|
|
578
|
+
when HIR::LoadLocal
|
|
579
|
+
var_name = value.var.name.to_s
|
|
580
|
+
if block_param_names.include?(var_name)
|
|
581
|
+
value
|
|
582
|
+
else
|
|
583
|
+
new_var = HIR::LocalVar.new(name: prefix + var_name, type: value.var.type)
|
|
584
|
+
HIR::LoadLocal.new(var: new_var, type: value.type, result_var: nil)
|
|
585
|
+
end
|
|
586
|
+
else
|
|
587
|
+
value
|
|
588
|
+
end
|
|
589
|
+
end
|
|
484
590
|
end
|
|
485
591
|
end
|
|
486
592
|
end
|
data/lib/konpeito/hir/builder.rb
CHANGED
|
@@ -4038,13 +4038,15 @@ module Konpeito
|
|
|
4038
4038
|
key_var = param_names[0] || "k"
|
|
4039
4039
|
value_var = param_names[1] || "v"
|
|
4040
4040
|
|
|
4041
|
-
# Build block body
|
|
4041
|
+
# Build block body — save/restore @current_block so NativeHashEach
|
|
4042
|
+
# is emitted into the original block, not the loop body block
|
|
4043
|
+
saved_block = @current_block
|
|
4042
4044
|
body_child = block_child.children.find { |c| c.node_type == :statements }
|
|
4043
4045
|
block_body = []
|
|
4044
4046
|
|
|
4045
4047
|
if body_child
|
|
4046
4048
|
# Create a new basic block for the iteration body
|
|
4047
|
-
loop_bb = BasicBlock.new(label:
|
|
4049
|
+
loop_bb = BasicBlock.new(label: "hash_each_body_#{@block_counter}")
|
|
4048
4050
|
@current_block = loop_bb
|
|
4049
4051
|
block_body << loop_bb
|
|
4050
4052
|
|
|
@@ -4052,6 +4054,7 @@ module Konpeito
|
|
|
4052
4054
|
visit(stmt)
|
|
4053
4055
|
end
|
|
4054
4056
|
end
|
|
4057
|
+
@current_block = saved_block
|
|
4055
4058
|
|
|
4056
4059
|
result_var = new_temp_var
|
|
4057
4060
|
inst = NativeHashEach.new(
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* yyjson_wrapper.c - Non-inline wrappers for yyjson functions
|
|
3
|
+
*
|
|
4
|
+
* yyjson uses static inline functions in its header. When linking with
|
|
5
|
+
* LLVM-generated code, we need non-inline versions that can be called
|
|
6
|
+
* via external symbol references. This file provides those wrappers.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include "yyjson.h"
|
|
10
|
+
#include <stddef.h>
|
|
11
|
+
#include <stdint.h>
|
|
12
|
+
#include <stdbool.h>
|
|
13
|
+
|
|
14
|
+
yyjson_doc *konpeito_yyjson_read(const char *dat, size_t len, yyjson_read_flag flg) {
|
|
15
|
+
return yyjson_read(dat, len, flg);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
yyjson_val *konpeito_yyjson_doc_get_root(yyjson_doc *doc) {
|
|
19
|
+
return yyjson_doc_get_root(doc);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void konpeito_yyjson_doc_free(yyjson_doc *doc) {
|
|
23
|
+
yyjson_doc_free(doc);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
yyjson_val *konpeito_yyjson_obj_get(yyjson_val *obj, const char *key) {
|
|
27
|
+
return yyjson_obj_get(obj, key);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
int64_t konpeito_yyjson_get_sint(yyjson_val *val) {
|
|
31
|
+
return yyjson_get_sint(val);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
uint64_t konpeito_yyjson_get_uint(yyjson_val *val) {
|
|
35
|
+
return yyjson_get_uint(val);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
double konpeito_yyjson_get_real(yyjson_val *val) {
|
|
39
|
+
return yyjson_get_real(val);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
bool konpeito_yyjson_get_bool(yyjson_val *val) {
|
|
43
|
+
return yyjson_get_bool(val);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const char *konpeito_yyjson_get_str(yyjson_val *val) {
|
|
47
|
+
return yyjson_get_str(val);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
size_t konpeito_yyjson_get_len(yyjson_val *val) {
|
|
51
|
+
return yyjson_get_len(val);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
size_t konpeito_yyjson_arr_size(yyjson_val *arr) {
|
|
55
|
+
return yyjson_arr_size(arr);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
yyjson_val *konpeito_yyjson_arr_get(yyjson_val *arr, size_t idx) {
|
|
59
|
+
return yyjson_arr_get(arr, idx);
|
|
60
|
+
}
|
data/lib/konpeito/version.rb
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Setup vendored dependencies for Konpeito
|
|
3
|
+
#
|
|
4
|
+
# Downloads yyjson (fast JSON library) source files.
|
|
5
|
+
# Run this after cloning the repository:
|
|
6
|
+
# bash scripts/setup_vendor.sh
|
|
7
|
+
|
|
8
|
+
set -e
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
12
|
+
YYJSON_DIR="$PROJECT_ROOT/vendor/yyjson"
|
|
13
|
+
|
|
14
|
+
YYJSON_VERSION="0.10.0"
|
|
15
|
+
YYJSON_BASE_URL="https://raw.githubusercontent.com/ibireme/yyjson/${YYJSON_VERSION}/src"
|
|
16
|
+
|
|
17
|
+
echo "Setting up vendored dependencies..."
|
|
18
|
+
|
|
19
|
+
# --- yyjson ---
|
|
20
|
+
mkdir -p "$YYJSON_DIR"
|
|
21
|
+
|
|
22
|
+
if [ -f "$YYJSON_DIR/yyjson.h" ] && [ -f "$YYJSON_DIR/yyjson.c" ]; then
|
|
23
|
+
echo " yyjson: already present (skipping download)"
|
|
24
|
+
else
|
|
25
|
+
echo " yyjson: downloading v${YYJSON_VERSION}..."
|
|
26
|
+
curl -sL "${YYJSON_BASE_URL}/yyjson.h" -o "$YYJSON_DIR/yyjson.h"
|
|
27
|
+
curl -sL "${YYJSON_BASE_URL}/yyjson.c" -o "$YYJSON_DIR/yyjson.c"
|
|
28
|
+
echo " yyjson: downloaded yyjson.h and yyjson.c"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
echo ""
|
|
32
|
+
echo "Done. Vendor dependencies are ready."
|
|
33
|
+
echo " yyjson: $YYJSON_DIR"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: konpeito
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yasushi Itoh
|
|
@@ -131,6 +131,7 @@ files:
|
|
|
131
131
|
- lib/konpeito/stdlib/json/json.rb
|
|
132
132
|
- lib/konpeito/stdlib/json/json.rbs
|
|
133
133
|
- lib/konpeito/stdlib/json/json_native.c
|
|
134
|
+
- lib/konpeito/stdlib/json/yyjson_wrapper.c
|
|
134
135
|
- lib/konpeito/stdlib/ui/extconf.rb
|
|
135
136
|
- lib/konpeito/stdlib/ui/konpeito_ui_native.cpp
|
|
136
137
|
- lib/konpeito/stdlib/ui/konpeito_ui_native.h
|
|
@@ -202,6 +203,7 @@ files:
|
|
|
202
203
|
- lib/konpeito/ui/widgets/text.rb
|
|
203
204
|
- lib/konpeito/ui/widgets/tree.rb
|
|
204
205
|
- lib/konpeito/version.rb
|
|
206
|
+
- scripts/setup_vendor.sh
|
|
205
207
|
- test_native_array.rb
|
|
206
208
|
- test_native_array_class.rb
|
|
207
209
|
- test_native_class.rb
|