@@ -2661,6 +2661,58 @@ nosplat(node *t)
26612661return TRUE;
26622662}
266326632664+/* Check if node is a simple literal that can be generated into any register */
2665+static mrb_bool
2666+is_simple_literal(node *n)
2667+{
2668+switch (get_node_type(n)) {
2669+case NODE_INT:
2670+case NODE_NIL:
2671+case NODE_TRUE:
2672+case NODE_FALSE:
2673+return TRUE;
2674+default:
2675+return FALSE;
2676+ }
2677+}
2678+2679+/* Check if all lhs are local variables and get their registers */
2680+static mrb_bool
2681+all_lvar_pre(codegen_scope *s, node *pre, int *regs, int max)
2682+{
2683+int i = 0;
2684+while (pre && i < max) {
2685+if (get_node_type(pre->car) != NODE_LVAR) return FALSE;
2686+int idx = lv_idx(s, var_node(pre->car)->symbol);
2687+if (idx <= 0) return FALSE; /* not a local variable */
2688+regs[i++] = idx;
2689+pre = pre->cdr;
2690+ }
2691+return pre == NULL; /* all processed */
2692+}
2693+2694+/* Generate a simple literal directly into a specific register */
2695+static void
2696+gen_literal_to_reg(codegen_scope *s, node *n, int reg)
2697+{
2698+switch (get_node_type(n)) {
2699+case NODE_INT:
2700+gen_int(s, reg, int_node(n)->value);
2701+break;
2702+case NODE_NIL:
2703+genop_1(s, OP_LOADNIL, reg);
2704+break;
2705+case NODE_TRUE:
2706+genop_1(s, OP_LOADT, reg);
2707+break;
2708+case NODE_FALSE:
2709+genop_1(s, OP_LOADF, reg);
2710+break;
2711+default:
2712+break;
2713+ }
2714+}
2715+26642716static mrb_sym
26652717attrsym(codegen_scope *s, mrb_sym a)
26662718{
@@ -4974,6 +5026,37 @@ codegen_masgn(codegen_scope *s, node *varnode, node *rhs, int sp, int val)
49745026if (an->elements && nosplat(an->elements)) {
49755027/* fixed rhs */
49765028t = an->elements;
5029+5030+/* Optimization: direct generation for simple cases */
5031+/* When all lhs are local vars and all rhs are simple literals, */
5032+/* generate directly into target registers (no temporaries) */
5033+if (masgn_n->pre && !masgn_n->rest && !masgn_n->post) {
5034+int regs[16]; /* support up to 16 variables */
5035+node *lhs = masgn_n->pre;
5036+node *rhs_elem = t;
5037+int count = 0;
5038+mrb_bool all_simple = TRUE;
5039+5040+/* Count and check rhs are all simple literals */
5041+while (rhs_elem && count < 16) {
5042+if (!is_simple_literal(rhs_elem->car)) {
5043+all_simple = FALSE;
5044+break;
5045+ }
5046+count++;
5047+rhs_elem = rhs_elem->cdr;
5048+ }
5049+if (all_simple && count > 0 && all_lvar_pre(s, lhs, regs, count)) {
5050+/* Direct generation: generate literals into target registers */
5051+rhs_elem = t;
5052+for (int i = 0; i < count; i++) {
5053+gen_literal_to_reg(s, rhs_elem->car, regs[i]);
5054+rhs_elem = rhs_elem->cdr;
5055+ }
5056+return;
5057+ }
5058+ }
5059+49775060rhs_reg = cursp(); /* Save register where values will be pushed */
49785061while (t) {
49795062codegen(s, t->car, VAL);