123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223(*
* Copyright (c) 2014 Jeremy Yallop.
*
* This file is distributed under the terms of the MIT License.
* See the file LICENSE for details.
*)(* C code representation. *)[@@@warning"-9"]openCtypes_staticletfresh_var=letvar_counter=ref0infun?(prefix="x")()->incrvar_counter;Printf.sprintf"%s%d"prefix!var_countertypety=Ty:_typ->tytypetfn=Fn:_fn->tfntypefieldname=stringtypecfunction={fname:string;allocates:bool;reads_ocaml_heap:bool;fn:tfn;}typecglobal={name:string;typ:ty;references_ocaml_heap:bool;}typeclocal=[`Localofstring*ty]typecvar=[clocal|`Globalofcglobal]typestorage_class=[`Static|`Extern]typecconst=[`IntofSigned.sint]typecexp=[cconst|clocal|`Castofty*cexp|`Addrofcvar]typeclvalue=[cvar|`Indexofclvalue*cexp|`Fieldofclvalue*fieldname|`PointerFieldofclvalue*fieldname]typecamlop=[`CAMLparam0|`CAMLlocalNofcexp*cexp|`CAMLdrop]typeceff=[cexp|camlop|`Globalofcglobal|`Appofcfunction*cexplist|`Indexofceff*cexp|`Derefofcexp|`DerefFieldofcexp*fieldname]typecbind=clocal*cefftypeccomp=[ceff|`CAMLparamofstringlist*ccomp|`LetConstofclocal*cconst*ccomp|`LetAssignofclvalue*ceff*ccomp|`CAMLreturnTofty*cexp|`Returnofty*cexp|`Letofcbind*ccomp]typecfundec=[`Fundecofstring*(string*ty)list*ty]typecfundef=[`Functionofcfundec*ccomp*storage_class]letrecreturn_type:typea.afn->ty=function|Function(_,f)->return_typef|Returnst->Tytletargs:typea.afn->(string*ty)list=funfn->letrecloop:typea.aCtypes.fn->(string*ty)list=function|Ctypes_static.Function(ty,fn)->(fresh_var(),Tyty)::loopfn|Ctypes_static.Returns_->[]inloopfnmoduleType_C=structletcexp:cexp->ty=function|`Int_->Tysint|`Local(_,ty)->ty|`Cast(Tyty,_)->Tyty|`Addr(`Global{typ=Tyty})->Ty(Pointerty)|`Addr(`Local(_,Tyty))->Ty(Pointerty)letcamlop:camlop->ty=function|`CAMLparam0|`CAMLlocalN_|`CAMLdrop->TyVoidletrecceff:ceff->ty=function|#cexpase->cexpe|#camlopaso->camlopo|`Global{typ}->typ|`App({fn=Fnf},_)->return_typef|`Index(e,_)->reference_ceffe|`Derefe->reference_ceff(e:>ceff)|`DerefField(e,f)->field_ceff(e:>ceff)fandreference_ceff:ceff->ty=fune->beginmatchceffewith|Ty(Pointerty)->Tyty|Ty(Array(ty,_))->Tyty|Tyt->Cstubs_errors.internal_error"dereferencing expression of non-pointer type %s"(Ctypes.string_of_typt)endandfield_ceff:ceff->fieldname->ty=funef->beginmatchceffewithTy(Pointer(Struct{fields}ass))->lookup_fieldfsfields|Tyt->Cstubs_errors.internal_error"accessing a field %s in an expression of type %s, which is not a pointer-to-struct type"f(Ctypes.string_of_typt)endandlookup_field:typesa.string->atyp->sboxed_fieldlist->ty=funftyfields->matchfieldswith[]->Cstubs_errors.internal_error"field %s not found in struct %s"f(Ctypes.string_of_typty)|BoxedField{ftype;fname}::_whenfname=f->Tyftype|_::fields->lookup_fieldftyfieldsletrecccomp:ccomp->ty=function|#cexpase->cexpe|#ceffase->ceffe|`CAMLparam(_,c)->ccompc|`Let(_,c)|`LetConst(_,_,c)->ccompc|`LetAssign(_,_,c)->ccompc|`CAMLreturnT(ty,_)->ty|`Return(ty,_)->tyendletvalue:[`value]abstracttyp=abstract~name:"value"~size:0~alignment:0letreaderfnamefn={fname;allocates=false;reads_ocaml_heap=true;fn=Fnfn}letconserfnamefn={fname;allocates=true;reads_ocaml_heap=false;fn=Fnfn}letimmediaterfnamefn={fname;allocates=false;reads_ocaml_heap=false;fn=Fnfn}moduleUnchecked_function_types=struct(* We're using an abstract type ([value]) as an argument and return type, so
we'll use the [Function] and [Return] constructors directly. The smart
constructors [@->] and [returning] would reject the abstract type. *)let(@->)ft=Function(f,t)letreturningt=Returnstendletprim_prj:typea.aCtypes_primitive_types.prim->_=letopenUnchecked_function_typesinletopenCtypes_primitive_typesinfunction|Char->reader"Int_val"(value@->returningint)|Schar->reader"Int_val"(value@->returningint)|Uchar->reader"Uint8_val"(value@->returninguint8_t)|Bool->reader"Bool_val"(value@->returningbool)|Short->reader"Int_val"(value@->returningint)|Int->reader"Long_val"(value@->returningint)|Long->reader"ctypes_long_val"(value@->returninglong)|Llong->reader"ctypes_llong_val"(value@->returningllong)|Ushort->reader"ctypes_ushort_val"(value@->returningushort)|Sint->reader"ctypes_sint_val"(value@->returningsint)|Uint->reader"ctypes_uint_val"(value@->returninguint)|Ulong->reader"ctypes_ulong_val"(value@->returningulong)|Ullong->reader"ctypes_ullong_val"(value@->returningullong)|Size_t->reader"ctypes_size_t_val"(value@->returningsize_t)|Int8_t->reader"Int_val"(value@->returningint)|Int16_t->reader"Int_val"(value@->returningint)|Int32_t->reader"Int32_val"(value@->returningint32_t)|Int64_t->reader"Int64_val"(value@->returningint64_t)|Uint8_t->reader"Uint8_val"(value@->returninguint8_t)|Uint16_t->reader"Uint16_val"(value@->returninguint16_t)|Uint32_t->reader"Uint32_val"(value@->returninguint32_t)|Uint64_t->reader"Uint64_val"(value@->returninguint64_t)|Camlint->reader"Long_val"(value@->returningint)|Nativeint->reader"Nativeint_val"(value@->returningnativeint)|Float->reader"Double_val"(value@->returningdouble)|Double->reader"Double_val"(value@->returningdouble)|LDouble->reader"ctypes_ldouble_val"(value@->returningldouble)|Complex32->reader"ctypes_float_complex_val"(value@->returningcomplex32)|Complex64->reader"ctypes_double_complex_val"(value@->returningcomplex64)|Complexld->reader"ctypes_ldouble_complex_val"(value@->returningcomplexld)letprim_inj:typea.aCtypes_primitive_types.prim->_=letopenUnchecked_function_typesinletopenCtypes_primitive_typesinfunction|Char->immediater"Ctypes_val_char"(int@->returningvalue)|Schar->immediater"Val_int"(int@->returningvalue)|Uchar->immediater"Integers_val_uint8"(uint8_t@->returningvalue)|Bool->immediater"Val_bool"(bool@->returningvalue)|Short->immediater"Val_int"(int@->returningvalue)|Int->immediater"Val_long"(int@->returningvalue)|Long->conser"ctypes_copy_long"(long@->returningvalue)|Llong->conser"ctypes_copy_llong"(llong@->returningvalue)|Ushort->conser"ctypes_copy_ushort"(ushort@->returningvalue)|Sint->conser"ctypes_copy_sint"(sint@->returningvalue)|Uint->conser"ctypes_copy_uint"(uint@->returningvalue)|Ulong->conser"ctypes_copy_ulong"(ulong@->returningvalue)|Ullong->conser"ctypes_copy_ullong"(ullong@->returningvalue)|Size_t->conser"ctypes_copy_size_t"(size_t@->returningvalue)|Int8_t->immediater"Val_int"(int@->returningvalue)|Int16_t->immediater"Val_int"(int@->returningvalue)|Int32_t->conser"caml_copy_int32"(int32_t@->returningvalue)|Int64_t->conser"caml_copy_int64"(int64_t@->returningvalue)|Uint8_t->immediater"Integers_val_uint8"(uint8_t@->returningvalue)|Uint16_t->immediater"Integers_val_uint16"(uint16_t@->returningvalue)|Uint32_t->conser"integers_copy_uint32"(uint32_t@->returningvalue)|Uint64_t->conser"integers_copy_uint64"(uint64_t@->returningvalue)|Camlint->immediater"Val_long"(int@->returningvalue)|Nativeint->conser"caml_copy_nativeint"(nativeint@->returningvalue)|Float->conser"caml_copy_double"(double@->returningvalue)|Double->conser"caml_copy_double"(double@->returningvalue)|LDouble->conser"ctypes_copy_ldouble"(ldouble@->returningvalue)|Complex32->conser"ctypes_copy_float_complex"(complex32@->returningvalue)|Complex64->conser"ctypes_copy_double_complex"(complex64@->returningvalue)|Complexld->conser"ctypes_copy_ldouble_complex"(complexld@->returningvalue)