Tata Letak Penunjuk

Tata letak penunjuk menjelaskan penunjuk struktur atau array.

pointer_layout<>

Bidang pointer_layout<> terdiri dari karakter format FC_PP FC_PAD diikuti oleh satu atau beberapa deskripsi penunjuk, seperti yang dijelaskan nanti, dan berakhir dengan karakter format FC_END:

FC_PP
FC_PAD
{ pointer_instance_layout<> }*
FC_END

Bidang pointer_instance_layout<> adalah string format yang menjelaskan satu atau beberapa instans pointer. Bidang berikut digunakan dalam deskriptor ini:

  • offset_in_memory

    Offset yang ditandatangani ke lokasi penunjuk dalam memori. Untuk pointer yang berada dalam struktur, offset ini adalah offset negatif dari akhir struktur (akhir bagian struktur yang tidak konforman); untuk array, offset berasal dari awal array.

  • offset_in_buffer

    Offset yang ditandatangani ke lokasi penunjuk di buffer. Untuk penunjuk yang berada dalam struktur, offset ini adalah offset negatif dari akhir struktur (akhir bagian struktur yang tidak konforman): untuk array, offset berasal dari awal array.

  • offset_to_array

    Offset dari struktur penutup ke array tersemat yang penunjuknya sedang ditangani. Untuk array tingkat atas, bidang ini akan selalu nol.

  • perulangan

    Jumlah total pointer yang memiliki tata letak<> yang sama dijelaskan.

  • tahapan

    Tahapan antara pointer berturut-turut selama REPEAT.

  • number_of_pointers

    Jumlah pointer yang berbeda dalam instans berulang.

  • pointer_description

    Deskripsi penunjuk.

Semua tata letak instans pointer menggunakan satu pointer_instance<8> berikut:

offset_to_pointer_in_memory<2> 
offset_to_pointer_in_buffer<2> 
pointer_description<4>

Berikut ini adalah deskriptor instans:

Instans tunggal pointer ke jenis sederhana:

FC_NO_REPEAT FC_PAD 
pointer_instance<8>

Memperbaiki penunjuk berulang:

FC_FIXED_REPEAT FC_PAD 
iterations<2> 
increment<2> 
offset_to_array<2> 
number_of_pointers<2>
{ pointer_instance<8> }*

Penunjuk berulang variabel:

FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET) 
increment<2> 
offset_to_array<2> 
number_of_pointers<2> 
{ pointer_instance<8> }*

Untuk instans repeat dan variable repeat pointer tetap, ada sekumpulan deskripsi offset dan pointer untuk setiap pointer dalam instans pengulangan.

Masalah Desain Tata Letak Penunjuk

Bagian ini membahas masalah yang terkait dengan pemrosesan struktur yang sesuai dan penunjuk yang disematkan. Masalahnya adalah bahwa pengkompilasi menghasilkan tata letak penunjuk untuk struktur dan array dengan beberapa redundansi. Ini bermanfaat, karena informasi berguna dan dengan demikian, misalnya, struktur yang sesuai dapat berjalan satu tata letak penunjuk untuk melayani semua pointer dari struktur dan dari array yang sesuai menjadi bagian dari struktur yang sesuai. Namun, ada beberapa situasi tersemat yang mengharuskan mesin NDR melakukan pekerjaan tambahan untuk memproses semua tata letak penunjuk dalam urutan yang tepat, memproses setiap pointer tepat sekali.

Apa yang Dihasilkan Compiler

Setiap objek yang dibahas di bagian ini memiliki penunjuk, jadi misalnya, struktur yang sesuai memiliki penunjuk di bagian struktur serta dalam elemen array. Elemen ini adalah struktur sederhana dengan penunjuk.

  1. Struktur yang sesuai, tingkat tunggal

    Deskriptor yang sesuai memiliki bagian PP di mana semua pointer dijelaskan, baik dari struktur maupun dari array. Daftar anggota memiliki FC_LONG sebagai pengganti pointer. Deskriptor array CARRAY memiliki elemen melalui penggunaan embedded_complex dan tidak ada deskriptor pointer sama sekali. Elemen masih memiliki deskriptor penunjuk tunggalnya. Tata letak penunjuk mendahului tata letak anggota dalam struktur yang sesuai dan deskriptor struktur sederhana.

  2. Struktur yang sesuai, dua tingkat atau lebih

    Deskripsi PP memiliki pointer dari semua tingkatan. Ini menggunakan kembali deskripsi array yang sama dengan struktur internal yang sesuai. Daftar anggota memiliki FC_LONG sebagai pengganti pointer. Struktur yang disematkan hadir melalui penggunaan kompleks yang disematkan. Deskriptor struktur yang sesuai digunakan kembali apa adanya. Ukuran bagian datar struktur juga keluar lengkap, yang berarti bahwa ukuran struktur tingkat atas akan mencakup ukuran datar struktur yang disematkan.

  3. Struktur kompleks, tingkat tunggal

    Anggota penunjuk ditandai dengan FC_POINTER. Tata letak penunjuk disederhanakan sehingga ada deskriptor penunjuk (4 byte) untuk setiap entri FC_POINTER dalam daftar. Tata letak penunjuk berjalan secara paralel dengan anggota berjalan, yaitu FC_POINTER menyebabkan deskripsi penunjuk berikutnya diproses. Array CARRAY memiliki tata letak penunjuk dengan semua deskriptor array, lalu elemen, melalui penggunaan kompleks yang disematkan. Deskriptor elemen digunakan kembali. Ukuran bagian datar struktur keluar lengkap; dengan kata lain, ukuran datar struktur tingkat atas mencakup ukuran datar struktur yang disematkan. Tata letak anggota mendahului tata letak penunjuk untuk struktur yang kompleks.

    Oleh karena itu, pembuatan deskripsi array yang sesuai berbeda tergantung pada apakah itu array di dalam struktur yang sesuai atau di dalam struktur yang kompleks.

  4. Struktur kompleks, 2 tingkat atau lebih, kompleks dalam kompleks

    Struktur kompleks tingkat atas memiliki penunjuk anggotanya, struktur kompleks yang disematkan memiliki penunjuk anggotanya. Deskriptor struktur yang sesuai digunakan kembali. Deskriptor array dari bagian atas adalah array yang digunakan kembali dari struktur yang disematkan.

  5. Struktur kompleks dengan struktur yang sesuai tertanam

    Struktur sesuai tingkat atas memiliki penunjuk anggotanya. Deskriptor struktur yang sesuai digunakan kembali apa adanya. Deskriptor array digunakan kembali dari struktur sesuai yang disematkan; dengan kata lain, ia tidak memiliki penunjuk pada deskriptor array. Elemen memiliki deskriptor penunjuknya.

  6. Array struktur dengan pointer

    Array struktur sederhana dengan pointer dihasilkan sebagai SMFARRAY atau CARRAY tergantung apakah array berukuran, tetapi dalam kedua kasus memiliki tata letak penunjuk yang lengkap (FIXED_REPEAT atau VARIABLE_REPEAT). Tata letak penunjuk datang sebelum tata letak anggota.

    Array struktur kompleks dengan pointer dihasilkan sebagai BOGUS_ARRAY terlepas dari apakah itu tetap atau berukuran, dan dalam kedua kasus, tidak memiliki tata letak penunjuk.

Apa yang Dilakukan Mesin NDR

Bagian ini menjelaskan perilaku mesin NDR.

Marshaling pass

  1. Struktur yang sesuai dan struktur yang sesuai.

    Struktur tingkat atas berulah seperti struktur tingkat tunggal.

  2. Struktur kompleks yang disematkan dengan array yang sesuai

    Struktur kompleks apa pun memaksa struktur luar menjadi struktur yang kompleks. Struktur tersemat tidak pernah marshal array-nya. Setiap struktur selalu melewati penunjuk yang disematkan hanya dengan menghalalkan anggota dan anggota yang kebetulan menjadi FC_POINTER.

  3. Struktur kompleks dengan struktur yang sesuai

    Struktur konforman paling tertanam marshals array yang sesuai dan semua pointees. Mesin NDR tidak pernah turun ke struktur sesuai berlapis yang lebih dalam jika ada; ini menyederhanakan solusi, karena struktur yang sesuai adalah objek daun sejauh menyangkut marshal objek yang disematkan. Struktur kompleks tingkat atas melompati array marshaling.

Membatalkan amarshaling, bufsizing, dan freeing pass

Batal menikah bersifat simetris dengan marshaling; operasi pertama yang dilakukannya untuk struktur kompleks adalah mencari tahu lokasi pointees di buffer dengan cara memanggil fungsi NdrComplexStructBufferSize . Kemudian membatalkan nama pointees secara paralel, memungkinkan skema yang sama untuk membatalkan nama pointe dengan benar untuk digunakan. Seharusnya tidak ada kebingungan tentang objek dan serikat berukuran; gambar memori tidak boleh digunakan untuk objek dan serikat berukuran, hanya untuk konten buffer.

Bendera yang digunakan untuk melakukan marshaling dan unmarshaling dengan benar digunakan dengan cara yang sama dalam bufsizing dan freeing untuk memastikan bahwa pointees berjalan tepat sekali.

Endianess pass

Pada awalnya, endianess pass agak mirip dengan marshaling/unmarshaling; dua pass diperlukan untuk memproses struktur yang kompleks. Pass pertama mengonversi bagian datar dan menemukan lokasi pointees di buffer yang mirip dengan bagaimana bufsizing melakukan operasi ini untuk unmarshaling. Pass kedua kemudian mengonversi pointees.

Endianess lulus berbeda dengan cara berikut: setiap struktur dan setiap anggota harus dilangkahi sampai anggota daun atau elemen adalah jenis sederhana. Ini berbeda dari belum menikah; dalam belum menikah, misalnya, tidak pernah ada kebutuhan untuk memproses struktur yang sesuai yang disematkan dalam struktur yang sesuai, atau anggota struktur yang sesuai, untuk hal itu. Masalah lain adalah bahwa konversi bukan operasi idempoten —oleh karena itu pass yang belum menikah dapat mengulangi membatalkan amarshalasi beberapa bagian tanpa bahaya, sementara konversi harus dilakukan secara ketat sekali-per-setiap-sederhana-jenis.

Oleh karena itu, algoritma endianess dapat diringkas sebagai berikut. NDR memiliki gagasan tentang struktur yang sesuai tingkat atas dan bendera untuk menandainya, sebagaimana merujuknya. Saat berjalan pertama kali, seperti untuk mengonversi bagian datar dan untuk mendapatkan lokasi pointees, gagasan ini tidak akan digunakan. NDR akan turun melalui bagian datar dari semua tingkat struktur dan tidak pernah masuk ke pemrosesan pointer. Akhirnya, NDR akan mengonversi array di tingkat atas.

Saat berjalan untuk kedua kalinya, bendera akan digunakan untuk menandai pass pointer yang disematkan untuk menghindari memasuki tingkat struktur yang lebih dalam yang sesuai, lalu struktur paling sesuai. Dengan cara ini, bendera akan memaksa perilaku marshaling/unmarshaling umum, yaitu menghindari turun ke tingkat struktur yang lebih dalam yang sesuai.

Pass kedua untuk struktur kompleks dengan array yang sesuai berfungsi sebagai berikut: struktur kompleks bekerja dengan cara yang umum; yang berarti tingkat yang lebih dalam tidak akan pernah melihat atau melewati ukuran yang sesuai atau array yang sesuai, dan lebih suka berjalan anggota mereka tanpa menyentuh array.

Untuk struktur kompleks dengan struktur yang sesuai, struktur yang sesuai harus menyadari apakah itu tingkat atas, dan apakah itu dalam struktur yang kompleks. Bagian datar dari array diproses oleh struktur paling sesuai. Pada pass kedua, struktur paling sesuai akan melewati bagian datar dan melalui tata letak penunjuk dan kembali. Struktur paling kompleks akan melewati bagian datarnya, dan juga akan melewati tata letak penunjuk.

Aspek yang kuat dari endianess berjalan

Endianess walk memeriksa kondisi out-of-the-buffer yang biasa dan melakukan pemeriksaan lain dari sifat yang tidak terkait. Pemeriksaan yang ditujukan untuk nilai berkorelasi (seperti argumen ukuran versus ukuran yang sesuai) tidak dapat dilakukan menggunakan langkah ini; mereka dilakukan kemudian, ketika membatalkan amarshaling.