@@ -430,6 +430,38 @@ module Type = struct
430430 }
431431 ])
432432 })
433+
434+ let int_array_type =
435+ register_type " int_array" (fun () ->
436+ return
437+ { supertype = None
438+ ; final = true
439+ ; typ = W. Array { mut = true ; typ = Value I32 }
440+ })
441+
442+ let bigarray_type =
443+ register_type " bigarray" (fun () ->
444+ let * custom_operations = custom_operations_type in
445+ let * int_array = int_array_type in
446+ let * custom = custom_type in
447+ return
448+ { supertype = Some custom
449+ ; final = true
450+ ; typ =
451+ W. Struct
452+ [ { mut = false
453+ ; typ = Value (Ref { nullable = false ; typ = Type custom_operations })
454+ }
455+ ; { mut = true ; typ = Value (Ref { nullable = false ; typ = Extern }) }
456+ ; { mut = true ; typ = Value (Ref { nullable = false ; typ = Extern }) }
457+ ; { mut = false
458+ ; typ = Value (Ref { nullable = false ; typ = Type int_array })
459+ }
460+ ; { mut = false ; typ = Packed I8 }
461+ ; { mut = false ; typ = Packed I8 }
462+ ; { mut = false ; typ = Packed I8 }
463+ ]
464+ })
433465end
434466
435467module Value = struct
@@ -1373,6 +1405,235 @@ module Math = struct
13731405 let exp2 x = power (return (W. Const (F64 2. ))) x
13741406end
13751407
1408+ module Bigarray = struct
1409+ let dimension n a =
1410+ let * ty = Type. bigarray_type in
1411+ Memory. wasm_array_get
1412+ ~ty: Type. int_array_type
1413+ (Memory. wasm_struct_get ty (Memory. wasm_cast ty a) 3 )
1414+ (Arith. const (Int32. of_int n))
1415+
1416+ let get_at_offset ~(kind : Typing.Bigarray.kind ) a i =
1417+ let name, (typ : Wasm_ast.value_type ), size, box =
1418+ match kind with
1419+ | Float32 ->
1420+ ( " dv_get_f32"
1421+ , F32
1422+ , 2
1423+ , fun x ->
1424+ let * x = x in
1425+ return (W. F64PromoteF32 x) )
1426+ | Float64 -> " dv_get_f64" , F64 , 3 , Fun. id
1427+ | Int8_signed -> " dv_get_i8" , I32 , 0 , Fun. id
1428+ | Int8_unsigned -> " dv_get_ui8" , I32 , 0 , Fun. id
1429+ | Int16_signed -> " dv_get_i16" , I32 , 1 , Fun. id
1430+ | Int16_unsigned -> " dv_get_ui16" , I32 , 1 , Fun. id
1431+ | Int32 -> " dv_get_i32" , I32 , 2 , Fun. id
1432+ | Nativeint -> " dv_get_i32" , I32 , 2 , Fun. id
1433+ | Int64 -> " dv_get_i64" , I64 , 3 , Fun. id
1434+ | Int -> " dv_get_i32" , I32 , 2 , Fun. id
1435+ | Float16 ->
1436+ ( " dv_get_i16"
1437+ , I32
1438+ , 1
1439+ , fun x ->
1440+ let * conv =
1441+ register_import
1442+ ~name: " caml_float16_to_double"
1443+ (Fun { W. params = [ I32 ]; result = [ F64 ] })
1444+ in
1445+ let * x = x in
1446+ return (W. Call (conv, [ x ])) )
1447+ | Complex32 ->
1448+ ( " dv_get_f32"
1449+ , F32
1450+ , 3
1451+ , fun x ->
1452+ let * x = x in
1453+ return (W. F64PromoteF32 x) )
1454+ | Complex64 -> " dv_get_f64" , F64 , 4 , Fun. id
1455+ in
1456+ let * little_endian =
1457+ register_import
1458+ ~import_module: " bindings"
1459+ ~name: " littleEndian"
1460+ (Global { mut = false ; typ = I32 })
1461+ in
1462+ let * f =
1463+ register_import
1464+ ~import_module: " bindings"
1465+ ~name
1466+ (Fun
1467+ { W. params =
1468+ Ref { nullable = true ; typ = Extern }
1469+ :: I32
1470+ :: (if size = 0 then [] else [ I32 ])
1471+ ; result = [ typ ]
1472+ })
1473+ in
1474+ let * ty = Type. bigarray_type in
1475+ let * ta = Memory. wasm_struct_get ty (Memory. wasm_cast ty a) 2 in
1476+ let * ofs = Arith. (i lsl const (Int32. of_int size)) in
1477+ match kind with
1478+ | Float32
1479+ | Float64
1480+ | Int8_signed
1481+ | Int8_unsigned
1482+ | Int16_signed
1483+ | Int16_unsigned
1484+ | Int32
1485+ | Int64
1486+ | Int
1487+ | Nativeint
1488+ | Float16 ->
1489+ box
1490+ (return
1491+ (W. Call
1492+ (f, ta :: ofs :: (if size = 0 then [] else [ W. GlobalGet little_endian ]))))
1493+ | Complex32 | Complex64 ->
1494+ let delta = Int32. shift_left 1l (size - 1 ) in
1495+ let * ofs' = Arith. (return ofs + const delta) in
1496+ let * x = box (return (W. Call (f, [ ta; ofs; W. GlobalGet little_endian ]))) in
1497+ let * y = box (return (W. Call (f, [ ta; ofs'; W. GlobalGet little_endian ]))) in
1498+ let * ty = Type. float_array_type in
1499+ return (W. ArrayNewFixed (ty, [ x; y ]))
1500+
1501+ let set_at_offset ~kind a i v =
1502+ let name, (typ : Wasm_ast.value_type ), size, unbox =
1503+ match (kind : Typing.Bigarray.kind ) with
1504+ | Float32 ->
1505+ ( " dv_set_f32"
1506+ , F32
1507+ , 2
1508+ , fun x ->
1509+ let * x = x in
1510+ return (W. F32DemoteF64 x) )
1511+ | Float64 -> " dv_set_f64" , F64 , 3 , Fun. id
1512+ | Int8_signed | Int8_unsigned -> " dv_set_i8" , I32 , 0 , Fun. id
1513+ | Int16_signed | Int16_unsigned -> " dv_set_i16" , I32 , 1 , Fun. id
1514+ | Int32 -> " dv_set_i32" , I32 , 2 , Fun. id
1515+ | Nativeint -> " dv_set_i32" , I32 , 2 , Fun. id
1516+ | Int64 -> " dv_set_i64" , I64 , 3 , Fun. id
1517+ | Int -> " dv_set_i32" , I32 , 2 , Fun. id
1518+ | Float16 ->
1519+ ( " dv_set_i16"
1520+ , I32
1521+ , 1
1522+ , fun x ->
1523+ let * conv =
1524+ register_import
1525+ ~name: " caml_double_to_float16"
1526+ (Fun { W. params = [ F64 ]; result = [ I32 ] })
1527+ in
1528+ let * x = Fun. id x in
1529+ return (W. Call (conv, [ x ])) )
1530+ | Complex32 ->
1531+ ( " dv_set_f32"
1532+ , F32
1533+ , 3
1534+ , fun x ->
1535+ let * x = x in
1536+ return (W. F32DemoteF64 x) )
1537+ | Complex64 -> " dv_set_f64" , F64 , 4 , Fun. id
1538+ in
1539+ let * ty = Type. bigarray_type in
1540+ let * ta = Memory. wasm_struct_get ty (Memory. wasm_cast ty a) 2 in
1541+ let * ofs = Arith. (i lsl const (Int32. of_int size)) in
1542+ let * little_endian =
1543+ register_import
1544+ ~import_module: " bindings"
1545+ ~name: " littleEndian"
1546+ (Global { mut = false ; typ = I32 })
1547+ in
1548+ let * f =
1549+ register_import
1550+ ~import_module: " bindings"
1551+ ~name
1552+ (Fun
1553+ { W. params =
1554+ Ref { nullable = true ; typ = Extern }
1555+ :: I32
1556+ :: typ
1557+ :: (if size = 0 then [] else [ I32 ])
1558+ ; result = []
1559+ })
1560+ in
1561+ match kind with
1562+ | Float32
1563+ | Float64
1564+ | Int8_signed
1565+ | Int8_unsigned
1566+ | Int16_signed
1567+ | Int16_unsigned
1568+ | Int32
1569+ | Int64
1570+ | Int
1571+ | Nativeint
1572+ | Float16 ->
1573+ let * v = unbox v in
1574+ instr
1575+ (W. CallInstr
1576+ ( f
1577+ , ta :: ofs :: v :: (if size = 0 then [] else [ W. GlobalGet little_endian ])
1578+ ))
1579+ | Complex32 | Complex64 ->
1580+ let delta = Int32. shift_left 1l (size - 1 ) in
1581+ let * ofs' = Arith. (return ofs + const delta) in
1582+ let ty = Type. float_array_type in
1583+ let * x = unbox (Memory. wasm_array_get ~ty v (Arith. const 0l )) in
1584+ let * () = instr (W. CallInstr (f, [ ta; ofs; x; W. GlobalGet little_endian ])) in
1585+ let * y = unbox (Memory. wasm_array_get ~ty v (Arith. const 1l )) in
1586+ instr (W. CallInstr (f, [ ta; ofs'; y; W. GlobalGet little_endian ]))
1587+
1588+ let offset ~bound_error_index ~(layout : Typing.Bigarray.layout ) ta ~indices =
1589+ let l =
1590+ List. mapi
1591+ ~f: (fun pos i ->
1592+ let i =
1593+ match layout with
1594+ | C -> i
1595+ | Fortran -> Arith. (i - const 1l )
1596+ in
1597+ let i' = Code.Var. fresh () in
1598+ let dim = Code.Var. fresh () in
1599+ ( (let * () = store ~typ: I32 i' i in
1600+ let * () = store ~typ: I32 dim (dimension pos ta) in
1601+ let * cond = Arith. uge (load i') (load dim) in
1602+ instr (W. Br_if (bound_error_index, cond)))
1603+ , i'
1604+ , dim ))
1605+ indices
1606+ in
1607+ let l =
1608+ match layout with
1609+ | C -> l
1610+ | Fortran -> List. rev l
1611+ in
1612+ match l with
1613+ | (instrs , i' , _ ) :: rem ->
1614+ List. fold_left
1615+ ~f: (fun (instrs , ofs ) (instrs' , i' , dim ) ->
1616+ let ofs' = Code.Var. fresh () in
1617+ ( (let * () = instrs in
1618+ let * () = instrs' in
1619+ store ~typ: I32 ofs' Arith. ((ofs * load dim) + load i'))
1620+ , load ofs' ))
1621+ ~init: (instrs, load i')
1622+ rem
1623+ | [] -> return () , Arith. const 0l
1624+
1625+ let get ~bound_error_index ~kind ~layout ta ~indices =
1626+ let instrs, ofs = offset ~bound_error_index ~layout ta ~indices in
1627+ seq instrs (get_at_offset ~kind ta ofs)
1628+
1629+ let set ~bound_error_index ~kind ~layout ta ~indices v =
1630+ let instrs, ofs = offset ~bound_error_index ~layout ta ~indices in
1631+ seq
1632+ (let * () = instrs in
1633+ set_at_offset ~kind ta ofs v)
1634+ Value. unit
1635+ end
1636+
13761637module JavaScript = struct
13771638 let anyref = W. Ref { nullable = true ; typ = Any }
13781639
0 commit comments