koffi 3.0.0 → 3.0.1

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.
@@ -29,15 +29,15 @@ enum class AbiOpcode {
29
29
  #define PRIMITIVE(Name) Push ## Name,
30
30
  #include "../primitives.inc"
31
31
  PushAggregateReg,
32
- PushAggregateStack,
32
+ PushAggregateMem,
33
33
  #define PRIMITIVE(Name) Run ## Name,
34
34
  #include "../primitives.inc"
35
35
  RunAggregateReg,
36
- RunAggregateStack,
36
+ RunAggregateMem,
37
37
  #define PRIMITIVE(Name) Run ## Name ## X,
38
38
  #include "../primitives.inc"
39
39
  RunAggregateRegX,
40
- RunAggregateStackX,
40
+ RunAggregateMemX,
41
41
  Yield,
42
42
  CallG,
43
43
  CallF,
@@ -50,12 +50,12 @@ enum class AbiOpcode {
50
50
  #define PRIMITIVE(Name) Return ## Name,
51
51
  #include "../primitives.inc"
52
52
  ReturnAggregateReg,
53
- ReturnAggregateStack
53
+ ReturnAggregateMem
54
54
  };
55
55
 
56
56
  namespace {
57
57
  #if defined(MUST_TAIL)
58
- PRESERVE_NONE typedef napi_value ForwardFunc(CallData *call, napi_value *args, uint64_t *base, const AbiInstruction *inst);
58
+ PRESERVE_NONE typedef napi_value ForwardFunc(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst);
59
59
 
60
60
  extern ForwardFunc *const ForwardDispatch[256];
61
61
 
@@ -82,16 +82,16 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
82
82
  param.regular = IsRegularSize(param.type->size, 8);
83
83
 
84
84
  if (param.type->primitive == PrimitiveKind::Record || param.type->primitive == PrimitiveKind::Union) {
85
- AbiOpcode code = param.regular ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateStack;
85
+ AbiOpcode code = param.regular ? AbiOpcode::PushAggregateReg : AbiOpcode::PushAggregateMem;
86
86
 
87
- func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = arg, .b2 = (int16_t)param.directions, .type = param.type });
88
- func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = arg, .b2 = (int16_t)param.directions, .type = param.type });
87
+ func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
88
+ func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
89
89
  } else {
90
90
  int delta = (int)AbiOpcode::PushVoid - (int)PrimitiveKind::Void;
91
91
  AbiOpcode code = (AbiOpcode)((int)param.type->primitive + delta);
92
92
 
93
- func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = arg, .b2 = (int16_t)param.directions, .type = param.type });
94
- func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = arg, .b2 = (int16_t)param.directions, .type = param.type });
93
+ func->sync.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
94
+ func->async.Append({ .op = Code2Op(code), .a = param.offset, .b1 = (int16_t)(arg * 8), .b2 = (int16_t)param.directions, .type = param.type });
95
95
  }
96
96
 
97
97
  func->forward_fp |= IsFloat(param.type);
@@ -175,12 +175,12 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
175
175
  func->async.Append({ .op = Code2Op(call) });
176
176
  func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateReg), .type = func->ret.type });
177
177
  } else {
178
- AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateStackX : AbiOpcode::RunAggregateStack;
178
+ AbiOpcode run = func->forward_fp ? AbiOpcode::RunAggregateMemX : AbiOpcode::RunAggregateMem;
179
179
  AbiOpcode call = func->forward_fp ? AbiOpcode::CallStackX : AbiOpcode::CallStack;
180
180
 
181
181
  func->sync.Append({ .op = Code2Op(run), .a = (int32_t)func->ret.type->size, .type = func->ret.type });
182
182
  func->async.Append({ .op = Code2Op(call), .a = (int32_t)func->ret.type->size });
183
- func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateStack), .type = func->ret.type });
183
+ func->async.Append({ .op = Code2Op(AbiOpcode::ReturnAggregateMem), .type = func->ret.type });
184
184
  }
185
185
  } break;
186
186
  case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
@@ -216,7 +216,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
216
216
  namespace {
217
217
  #if defined(MUST_TAIL)
218
218
  #define OP(Code) \
219
- PRESERVE_NONE napi_value Handle ## Code(CallData *call, napi_value *args, uint64_t *base, const AbiInstruction *inst)
219
+ PRESERVE_NONE napi_value Handle ## Code(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
220
220
  #define NEXT() \
221
221
  do { \
222
222
  const AbiInstruction *next = inst + 1; \
@@ -228,7 +228,7 @@ namespace {
228
228
  #define NEXT() \
229
229
  break
230
230
 
231
- napi_value RunLoop(CallData *call, napi_value *args, uint64_t *base, const AbiInstruction *inst)
231
+ napi_value RunLoop(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
232
232
  {
233
233
  for (;; ++inst) {
234
234
  switch ((intptr_t)inst->op) {
@@ -255,7 +255,7 @@ namespace {
255
255
  return call->env.Null(); \
256
256
  } \
257
257
  \
258
- *(base + inst->b1) = (uint64_t)v; \
258
+ *(uint64_t *)(base + inst->b1) = (uint64_t)v; \
259
259
  } while (false)
260
260
  #define INTEGER_SWAP(CType) \
261
261
  do { \
@@ -265,7 +265,7 @@ namespace {
265
265
  return call->env.Null(); \
266
266
  } \
267
267
  \
268
- *(base + inst->b1) = (uint64_t)ReverseBytes(v); \
268
+ *(uint64_t *)(base + inst->b1) = (uint64_t)ReverseBytes(v); \
269
269
  } while (false)
270
270
 
271
271
  OP(PushVoid) { K_UNREACHABLE(); return call->env.Null(); }
@@ -381,7 +381,7 @@ namespace {
381
381
 
382
382
  NEXT();
383
383
  }
384
- OP(PushAggregateStack) {
384
+ OP(PushAggregateMem) {
385
385
  napi_value arg = args[inst->a];
386
386
 
387
387
  if (!IsObject(call->env, arg)) [[unlikely]] {
@@ -403,12 +403,12 @@ namespace {
403
403
 
404
404
  #define INTEGER(Suffix, CType) \
405
405
  do { \
406
- uint64_t rax = WRAP(ForwardCall ## Suffix(call->native, (uint8_t *)base, &call->saved_sp)); \
406
+ uint64_t rax = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
407
407
  return NewInt(call->env, (CType)rax); \
408
408
  } while (false)
409
409
  #define INTEGER_SWAP(Suffix, CType) \
410
410
  do { \
411
- uint64_t rax = WRAP(ForwardCall ## Suffix(call->native, (uint8_t *)base, &call->saved_sp)); \
411
+ uint64_t rax = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
412
412
  return NewInt(call->env, ReverseBytes((CType)rax)); \
413
413
  } while (false)
414
414
  #define DISPOSE(Ptr) \
@@ -419,11 +419,11 @@ namespace {
419
419
  } while (false)
420
420
 
421
421
  OP(RunVoid) {
422
- WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
422
+ WRAP(ForwardCallG(call->native, base, &call->saved_sp));
423
423
  return nullptr;
424
424
  }
425
425
  OP(RunBool) {
426
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
426
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
427
427
  return Napi::Boolean::New(call->env, rax & 0x1);
428
428
  }
429
429
  OP(RunInt8) { INTEGER(G, int8_t); }
@@ -441,60 +441,60 @@ namespace {
441
441
  OP(RunUInt64) { INTEGER(G, uint64_t); }
442
442
  OP(RunUInt64S) { INTEGER_SWAP(G, uint64_t); }
443
443
  OP(RunString) {
444
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
444
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
445
445
  napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
446
446
  DISPOSE((void *)rax);
447
447
  return value;
448
448
  }
449
449
  OP(RunString16) {
450
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
450
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
451
451
  napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
452
452
  DISPOSE((void *)rax);
453
453
  return value;
454
454
  }
455
455
  OP(RunString32) {
456
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
456
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
457
457
  napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
458
458
  DISPOSE((void *)rax);
459
459
  return value;
460
460
  }
461
461
  OP(RunPointer) {
462
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
462
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
463
463
  napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
464
464
  DISPOSE((void *)rax);
465
465
  return value;
466
466
  }
467
467
  OP(RunCallback) {
468
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
468
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
469
469
  return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
470
470
  }
471
471
  OP(RunRecord) { K_UNREACHABLE(); return call->env.Null(); }
472
472
  OP(RunUnion) { K_UNREACHABLE(); return call->env.Null(); }
473
473
  OP(RunArray) { K_UNREACHABLE(); return call->env.Null(); }
474
474
  OP(RunFloat32) {
475
- float f = WRAP(ForwardCallF(call->native, (uint8_t *)base, &call->saved_sp));
475
+ float f = WRAP(ForwardCallF(call->native, base, &call->saved_sp));
476
476
  return Napi::Number::New(call->env, (double)f);
477
477
  }
478
478
  OP(RunFloat64) {
479
- double d = WRAP(ForwardCallD(call->native, (uint8_t *)base, &call->saved_sp));
479
+ double d = WRAP(ForwardCallD(call->native, base, &call->saved_sp));
480
480
  return Napi::Number::New(call->env, d);
481
481
  }
482
482
  OP(RunPrototype) { K_UNREACHABLE(); return call->env.Null(); }
483
483
  OP(RunAggregateReg) {
484
- auto ret = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
485
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
484
+ auto ret = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
485
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
486
486
  }
487
- OP(RunAggregateStack) {
487
+ OP(RunAggregateMem) {
488
488
  *(uint8_t **)base = call->AllocHeap(inst->a);
489
- uint64_t rax = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
490
- return DecodeObject(call->env, (const uint8_t *)rax, inst->type);
489
+ uint64_t rax = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
490
+ return DecodeObject(call->instance, (const uint8_t *)rax, inst->type);
491
491
  }
492
492
  OP(RunVoidX) {
493
- WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
493
+ WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
494
494
  return nullptr;
495
495
  }
496
496
  OP(RunBoolX) {
497
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
497
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
498
498
  return Napi::Boolean::New(call->env, rax & 0x1);
499
499
  }
500
500
  OP(RunInt8X) { INTEGER(GX, int8_t); }
@@ -512,53 +512,53 @@ namespace {
512
512
  OP(RunUInt64X) { INTEGER(GX, uint64_t); }
513
513
  OP(RunUInt64SX) { INTEGER_SWAP(GX, uint64_t); }
514
514
  OP(RunStringX) {
515
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
515
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
516
516
  napi_value value = rax ? Napi::String::New(call->env, (const char *)rax) : call->env.Null();
517
517
  DISPOSE((void *)rax);
518
518
  return value;
519
519
  }
520
520
  OP(RunString16X) {
521
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
521
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
522
522
  napi_value value = rax ? Napi::String::New(call->env, (const char16_t *)rax) : call->env.Null();
523
523
  DISPOSE((void *)rax);
524
524
  return value;
525
525
  }
526
526
  OP(RunString32X) {
527
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
527
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
528
528
  napi_value value = rax ? MakeStringFromUTF32(call->env, (const char32_t *)rax) : call->env.Null();
529
529
  DISPOSE((void *)rax);
530
530
  return value;
531
531
  }
532
532
  OP(RunPointerX) {
533
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
533
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
534
534
  napi_value value = rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
535
535
  DISPOSE((void *)rax);
536
536
  return value;
537
537
  }
538
538
  OP(RunCallbackX) {
539
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
539
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
540
540
  return rax ? WrapPointer(call->env, inst->type, (void *)rax) : call->env.Null();
541
541
  }
542
542
  OP(RunRecordX) { K_UNREACHABLE(); return call->env.Null(); }
543
543
  OP(RunUnionX) { K_UNREACHABLE(); return call->env.Null(); }
544
544
  OP(RunArrayX) { K_UNREACHABLE(); return call->env.Null(); }
545
545
  OP(RunFloat32X) {
546
- float f = WRAP(ForwardCallFX(call->native, (uint8_t *)base, &call->saved_sp));
546
+ float f = WRAP(ForwardCallFX(call->native, base, &call->saved_sp));
547
547
  return Napi::Number::New(call->env, (double)f);
548
548
  }
549
549
  OP(RunFloat64X) {
550
- double d = WRAP(ForwardCallDX(call->native, (uint8_t *)base, &call->saved_sp));
550
+ double d = WRAP(ForwardCallDX(call->native, base, &call->saved_sp));
551
551
  return Napi::Number::New(call->env, d);
552
552
  }
553
553
  OP(RunPrototypeX) { K_UNREACHABLE(); return call->env.Null(); }
554
554
  OP(RunAggregateRegX) {
555
- auto ret = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
556
- return DecodeObject(call->env, (const uint8_t *)&ret, inst->type);
555
+ auto ret = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
556
+ return DecodeObject(call->instance, (const uint8_t *)&ret, inst->type);
557
557
  }
558
- OP(RunAggregateStackX) {
558
+ OP(RunAggregateMemX) {
559
559
  *(uint8_t **)base = call->AllocHeap(inst->a);
560
- uint64_t rax = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
561
- return DecodeObject(call->env, (const uint8_t *)rax, inst->type);
560
+ uint64_t rax = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
561
+ return DecodeObject(call->instance, (const uint8_t *)rax, inst->type);
562
562
  }
563
563
 
564
564
  #undef DISPOSE
@@ -567,7 +567,7 @@ namespace {
567
567
 
568
568
  #define CALL(Suffix) \
569
569
  do { \
570
- auto ret = WRAP(ForwardCall ## Suffix(call->native, (uint8_t *)base, &call->saved_sp)); \
570
+ auto ret = WRAP(ForwardCall ## Suffix(call->native, base, &call->saved_sp)); \
571
571
  memcpy(base, &ret, K_SIZE(ret)); \
572
572
  } while (false)
573
573
  #define DISPOSE() \
@@ -598,7 +598,7 @@ namespace {
598
598
  OP(CallD) { CALL(D); return nullptr; }
599
599
  OP(CallStack) {
600
600
  *(uint8_t **)base = call->AllocHeap(inst->a);
601
- *(uint64_t *)base = WRAP(ForwardCallG(call->native, (uint8_t *)base, &call->saved_sp));
601
+ *(uint64_t *)base = WRAP(ForwardCallG(call->native, base, &call->saved_sp));
602
602
  return nullptr;
603
603
  }
604
604
  OP(CallGX) { CALL(GX); return nullptr; }
@@ -606,7 +606,7 @@ namespace {
606
606
  OP(CallDX) { CALL(DX); return nullptr; }
607
607
  OP(CallStackX) {
608
608
  *(uint8_t **)base = call->AllocHeap(inst->a);
609
- *(uint64_t *)base = WRAP(ForwardCallGX(call->native, (uint8_t *)base, &call->saved_sp));
609
+ *(uint64_t *)base = WRAP(ForwardCallGX(call->native, base, &call->saved_sp));
610
610
  return nullptr;
611
611
  }
612
612
 
@@ -669,10 +669,10 @@ namespace {
669
669
  return Napi::Number::New(call->env, d);
670
670
  }
671
671
  OP(ReturnPrototype) { K_UNREACHABLE(); return call->env.Null(); }
672
- OP(ReturnAggregateReg) { return DecodeObject(call->env, (const uint8_t *)base, inst->type); }
673
- OP(ReturnAggregateStack) {
672
+ OP(ReturnAggregateReg) { return DecodeObject(call->instance, base, inst->type); }
673
+ OP(ReturnAggregateMem) {
674
674
  uint64_t rax = *(uint64_t *)base;
675
- return DecodeObject(call->env, (const uint8_t *)rax, inst->type);
675
+ return DecodeObject(call->instance, (const uint8_t *)rax, inst->type);
676
676
  }
677
677
 
678
678
  #undef INTEGER_SWAP
@@ -685,15 +685,15 @@ namespace {
685
685
  #define PRIMITIVE(Name) HandlePush ## Name,
686
686
  #include "../primitives.inc"
687
687
  HandlePushAggregateReg,
688
- HandlePushAggregateStack,
688
+ HandlePushAggregateMem,
689
689
  #define PRIMITIVE(Name) HandleRun ## Name,
690
690
  #include "../primitives.inc"
691
691
  HandleRunAggregateReg,
692
- HandleRunAggregateStack,
692
+ HandleRunAggregateMem,
693
693
  #define PRIMITIVE(Name) HandleRun ## Name ## X,
694
694
  #include "../primitives.inc"
695
695
  HandleRunAggregateRegX,
696
- HandleRunAggregateStackX,
696
+ HandleRunAggregateMemX,
697
697
  HandleYield,
698
698
  HandleCallG,
699
699
  HandleCallF,
@@ -706,10 +706,10 @@ namespace {
706
706
  #define PRIMITIVE(Name) HandleReturn ## Name,
707
707
  #include "../primitives.inc"
708
708
  HandleReturnAggregateReg,
709
- HandleReturnAggregateStack
709
+ HandleReturnAggregateMem
710
710
  };
711
711
 
712
- FORCE_INLINE napi_value RunLoop(CallData *call, napi_value *args, uint64_t *base, const AbiInstruction *inst)
712
+ FORCE_INLINE napi_value RunLoop(CallData *call, napi_value *args, uint8_t *base, const AbiInstruction *inst)
713
713
  {
714
714
  return ((ForwardFunc *)inst->op)(call, args, base, inst);
715
715
  }
@@ -738,7 +738,7 @@ napi_value CallData::Run(const FunctionInfo *func, napi_value *args)
738
738
  return env.Null();
739
739
 
740
740
  const AbiInstruction *first = func->sync.ptr;
741
- return RunLoop(this, args, (uint64_t *)base, first);
741
+ return RunLoop(this, args, base, first);
742
742
  }
743
743
 
744
744
  bool CallData::PrepareAsync(const FunctionInfo *func, napi_value *args)
@@ -749,19 +749,19 @@ bool CallData::PrepareAsync(const FunctionInfo *func, napi_value *args)
749
749
  async_base = base;
750
750
 
751
751
  const AbiInstruction *first = func->async.ptr;
752
- return !RunLoop(this, args, (uint64_t *)base, first); // Yield returns nullptr
752
+ return !RunLoop(this, args, base, first); // Yield returns nullptr
753
753
  }
754
754
 
755
755
  void CallData::ExecuteAsync()
756
756
  {
757
757
  const AbiInstruction *next = async_ip++;
758
- RunLoop(this, nullptr, (uint64_t *)async_base, next);
758
+ RunLoop(this, nullptr, async_base, next);
759
759
  }
760
760
 
761
761
  napi_value CallData::EndAsync()
762
762
  {
763
763
  const AbiInstruction *next = async_ip++;
764
- return RunLoop(this, nullptr, (uint64_t *)async_base, next);
764
+ return RunLoop(this, nullptr, async_base, next);
765
765
  }
766
766
 
767
767
  void CallData::Relay(Size idx, uint8_t *sp)
@@ -944,7 +944,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
944
944
  }
945
945
  stk_ptr += (j >= 4);
946
946
 
947
- arguments[i] = DecodeObject(env, ptr, param.type);
947
+ arguments[i] = DecodeObject(instance, ptr, param.type);
948
948
  } break;
949
949
  case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
950
950
  case PrimitiveKind::Float32: {