3 * Copyright (C) 2006-2008, The Perl Foundation.
6 /* .NET CLI Bytecode PMC */
9 #include "parrot/extend.h"
10 #include "tableinfo.h"
11 #include "structures.h"
14 pmclass DotNetBytecode dynpmc group dotnet {
16 /* Instance initialization. We need a custom DOD marking and destroy. */
19 PObj_custom_mark_SET(SELF);
20 PObj_active_destroy_SET(SELF);
24 /* Garbage Collection mark routine. */
27 /* Tell the GC about stuff we're holding on to. */
28 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
30 pobject_lives(INTERP, (PObj *)bc->parent);
32 pobject_lives(INTERP, (PObj *)bc->eh);
39 /* Cleanup any memory we're using. */
40 if (PMC_struct_val(SELF)) {
41 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
43 mem_sys_free(bc->body);
45 PMC_struct_val(SELF) = NULL;
50 /* Get local variables signature blob location. */
51 METHOD INTVAL get_locals_sig()
53 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
56 /* Handle cases where we've an invalid PMC. */
58 real_exception(INTERP, NULL, E_StandardError,
59 "Invalid DotNetBytecode PMC");
61 result = (INTVAL)bc->locals_signature;
62 RETURN(INTVAL result);
66 /* Initialize local variables flag. */
67 METHOD INTVAL init_locals()
69 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
72 /* Handle cases where we've an invalid PMC. */
74 real_exception(INTERP, NULL, E_StandardError,
75 "Invalid DotNetBytecode PMC");
77 result = bc->init_locals_flag;
78 RETURN(INTVAL result);
82 /* Get length of bytecode. */
83 METHOD INTVAL get_length()
85 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
88 /* Handle cases where we've an invalid PMC. */
90 real_exception(INTERP, NULL, E_StandardError,
91 "Invalid DotNetBytecode PMC");
93 result = bc->body_size;
94 RETURN(INTVAL result);
98 /* Get current bytecode position, for when walking bytecode. */
99 METHOD INTVAL get_pos()
101 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
104 /* Handle cases where we've an invalid PMC. */
106 real_exception(INTERP, NULL, E_StandardError,
107 "Invalid DotNetBytecode PMC");
109 result = bc->cur_pos;
110 RETURN(INTVAL result);
114 /* Set current bytecode position, for when walking bytecode. */
115 METHOD void set_pos(INTVAL pos)
117 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
119 /* Handle cases where we've an invalid PMC. */
121 real_exception(INTERP, NULL, E_StandardError,
122 "Invalid DotNetBytecode PMC");
128 /* Get error handlers PMC array. */
131 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
134 /* Handle cases where we've an invalid PMC. */
136 real_exception(INTERP, NULL, E_StandardError,
137 "Invalid DotNetBytecode PMC");
144 /* Read a signed 8-bit integer. */
145 METHOD INTVAL read_int8()
147 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
150 /* Handle cases where we've an invalid PMC. */
152 real_exception(INTERP, NULL, E_StandardError,
153 "Invalid DotNetBytecode PMC");
155 /* Ensure we won't read past the end. */
156 if (bc->cur_pos >= bc->body_size)
157 real_exception(INTERP, NULL, E_StandardError,
158 "Read past end of bytecode");
160 /* Otherwise read the value. */
161 result = (INTVAL)bc->body[bc->cur_pos];
163 RETURN(INTVAL result);
167 /* Read an unsigned 8-bit integer. */
168 METHOD INTVAL read_uint8()
170 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
173 /* Handle cases where we've an invalid PMC. */
175 real_exception(INTERP, NULL, E_StandardError,
176 "Invalid DotNetBytecode PMC");
178 /* Ensure we won't read past the end. */
179 if (bc->cur_pos >= bc->body_size)
180 real_exception(INTERP, NULL, E_StandardError,
181 "Read past end of bytecode");
183 /* Otherwise read the value. */
184 result = (INTVAL)bc->body[bc->cur_pos];
186 RETURN(INTVAL result);
190 /* Read a signed 16-bit integer. */
191 METHOD INTVAL read_int16()
194 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
195 char *val_ptr = (char *)&result;
197 /* Handle cases where we've an invalid PMC. */
199 real_exception(INTERP, NULL, E_StandardError,
200 "Invalid DotNetBytecode PMC");
202 /* Ensure we won't read past the end. */
203 if (bc->cur_pos + 1 >= bc->body_size)
204 real_exception(INTERP, NULL, E_StandardError,
205 "Read past end of bytecode");
207 /* Otherwise read the value. */
208 if (PARROT_BIGENDIAN)
210 val_ptr[1] = bc->body[bc->cur_pos];
211 val_ptr[0] = bc->body[bc->cur_pos + 1];
215 val_ptr[0] = bc->body[bc->cur_pos];
216 val_ptr[1] = bc->body[bc->cur_pos + 1];
219 RETURN(INTVAL result);
223 /* Read an unsigned 16-bit integer. */
224 METHOD INTVAL read_uint16()
227 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
228 char *val_ptr = (char *)&result;
230 /* Handle cases where we've an invalid PMC. */
232 real_exception(INTERP, NULL, E_StandardError,
233 "Invalid DotNetBytecode PMC");
235 /* Ensure we won't read past the end. */
236 if (bc->cur_pos + 1 >= bc->body_size)
237 real_exception(INTERP, NULL, E_StandardError,
238 "Read past end of bytecode");
240 /* Otherwise read the value. */
241 if (PARROT_BIGENDIAN)
243 val_ptr[1] = bc->body[bc->cur_pos];
244 val_ptr[0] = bc->body[bc->cur_pos + 1];
248 val_ptr[0] = bc->body[bc->cur_pos];
249 val_ptr[1] = bc->body[bc->cur_pos + 1];
252 RETURN(INTVAL result);
256 /* Read a signed 32-bit integer. */
257 METHOD INTVAL read_int32()
260 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
261 char *val_ptr = (char *)&result;
263 /* Handle cases where we've an invalid PMC. */
265 real_exception(INTERP, NULL, E_StandardError,
266 "Invalid DotNetBytecode PMC");
268 /* Ensure we won't read past the end. */
269 if (bc->cur_pos + 3 >= bc->body_size)
270 real_exception(INTERP, NULL, E_StandardError,
271 "Read past end of bytecode");
273 /* Otherwise read the value. */
274 if (PARROT_BIGENDIAN)
276 val_ptr[3] = bc->body[bc->cur_pos];
277 val_ptr[2] = bc->body[bc->cur_pos + 1];
278 val_ptr[1] = bc->body[bc->cur_pos + 2];
279 val_ptr[0] = bc->body[bc->cur_pos + 3];
283 val_ptr[0] = bc->body[bc->cur_pos];
284 val_ptr[1] = bc->body[bc->cur_pos + 1];
285 val_ptr[2] = bc->body[bc->cur_pos + 2];
286 val_ptr[3] = bc->body[bc->cur_pos + 3];
289 RETURN(INTVAL result);
293 /* Read an unsigned 32-bit integer. */
294 METHOD INTVAL read_uint32()
297 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
298 char *val_ptr = (char *)&result;
300 /* Handle cases where we've an invalid PMC. */
302 real_exception(INTERP, NULL, E_StandardError,
303 "Invalid DotNetBytecode PMC");
305 /* Ensure we won't read past the end. */
306 if (bc->cur_pos + 3 >= bc->body_size)
307 real_exception(INTERP, NULL, E_StandardError,
308 "Read past end of bytecode");
310 /* Otherwise read the value. */
311 if (PARROT_BIGENDIAN)
313 val_ptr[3] = bc->body[bc->cur_pos];
314 val_ptr[2] = bc->body[bc->cur_pos + 1];
315 val_ptr[1] = bc->body[bc->cur_pos + 2];
316 val_ptr[0] = bc->body[bc->cur_pos + 3];
320 val_ptr[0] = bc->body[bc->cur_pos];
321 val_ptr[1] = bc->body[bc->cur_pos + 1];
322 val_ptr[2] = bc->body[bc->cur_pos + 2];
323 val_ptr[3] = bc->body[bc->cur_pos + 3];
326 RETURN(INTVAL result);
330 /* Read a 32-bit (single precision) floating pointer number. */
331 METHOD FLOATVAL read_float32()
334 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
335 char *val_ptr = (char *)&result;
337 /* Handle cases where we've an invalid PMC. */
339 real_exception(INTERP, NULL, E_StandardError,
340 "Invalid DotNetBytecode PMC");
342 /* Ensure we won't read past the end. */
343 if (bc->cur_pos + 3 >= bc->body_size)
344 real_exception(INTERP, NULL, E_StandardError,
345 "Read past end of bytecode");
347 /* Otherwise read the value. */
348 if (PARROT_BIGENDIAN)
350 val_ptr[3] = bc->body[bc->cur_pos];
351 val_ptr[2] = bc->body[bc->cur_pos + 1];
352 val_ptr[1] = bc->body[bc->cur_pos + 2];
353 val_ptr[0] = bc->body[bc->cur_pos + 3];
357 val_ptr[0] = bc->body[bc->cur_pos];
358 val_ptr[1] = bc->body[bc->cur_pos + 1];
359 val_ptr[2] = bc->body[bc->cur_pos + 2];
360 val_ptr[3] = bc->body[bc->cur_pos + 3];
363 RETURN(FLOATVAL result);
367 /* Read a 64-bit (double precision) floating pointer number. */
368 METHOD FLOATVAL read_float64()
372 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
373 char *val_ptr = (char *)&result;
375 /* Handle cases where we've an invalid PMC. */
377 real_exception(INTERP, NULL, E_StandardError,
378 "Invalid DotNetBytecode PMC");
380 /* Ensure we won't read past the end. */
381 if (bc->cur_pos + 7 >= bc->body_size)
382 real_exception(INTERP, NULL, E_StandardError,
383 "Read past end of bytecode");
385 /* Otherwise read the value. */
386 for (i = 0; i <= 4; i += 4) {
387 if (PARROT_BIGENDIAN)
389 val_ptr[i + 3] = bc->body[bc->cur_pos + i];
390 val_ptr[i + 2] = bc->body[bc->cur_pos + i + 1];
391 val_ptr[i + 1] = bc->body[bc->cur_pos + i + 2];
392 val_ptr[i] = bc->body[bc->cur_pos + i + 3];
396 val_ptr[i] = bc->body[bc->cur_pos + i];
397 val_ptr[i + 1] = bc->body[bc->cur_pos + i + 1];
398 val_ptr[i + 2] = bc->body[bc->cur_pos + i + 2];
399 val_ptr[i + 3] = bc->body[bc->cur_pos + i + 3];
403 RETURN(FLOATVAL result);
407 /* Read a field token (32 bits, unsigned). */
408 METHOD INTVAL read_tfield()
411 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
412 char *val_ptr = (char *)&result;
414 /* Handle cases where we've an invalid PMC. */
416 real_exception(INTERP, NULL, E_StandardError,
417 "Invalid DotNetBytecode PMC");
419 /* Ensure we won't read past the end. */
420 if (bc->cur_pos + 3 >= bc->body_size)
421 real_exception(INTERP, NULL, E_StandardError,
422 "Read past end of bytecode");
424 /* Otherwise read the value. */
425 if (PARROT_BIGENDIAN)
427 val_ptr[3] = bc->body[bc->cur_pos];
428 val_ptr[2] = bc->body[bc->cur_pos + 1];
429 val_ptr[1] = bc->body[bc->cur_pos + 2];
430 val_ptr[0] = bc->body[bc->cur_pos + 3];
434 val_ptr[0] = bc->body[bc->cur_pos];
435 val_ptr[1] = bc->body[bc->cur_pos + 1];
436 val_ptr[2] = bc->body[bc->cur_pos + 2];
437 val_ptr[3] = bc->body[bc->cur_pos + 3];
440 RETURN(INTVAL result);
444 /* Read a method token (32 bits, unsigned). */
445 METHOD INTVAL read_tmethod()
448 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
449 char *val_ptr = (char *)&result;
451 /* Handle cases where we've an invalid PMC. */
453 real_exception(INTERP, NULL, E_StandardError,
454 "Invalid DotNetBytecode PMC");
456 /* Ensure we won't read past the end. */
457 if (bc->cur_pos + 3 >= bc->body_size)
458 real_exception(INTERP, NULL, E_StandardError,
459 "Read past end of bytecode");
461 /* Otherwise read the value. */
462 if (PARROT_BIGENDIAN)
464 val_ptr[3] = bc->body[bc->cur_pos];
465 val_ptr[2] = bc->body[bc->cur_pos + 1];
466 val_ptr[1] = bc->body[bc->cur_pos + 2];
467 val_ptr[0] = bc->body[bc->cur_pos + 3];
471 val_ptr[0] = bc->body[bc->cur_pos];
472 val_ptr[1] = bc->body[bc->cur_pos + 1];
473 val_ptr[2] = bc->body[bc->cur_pos + 2];
474 val_ptr[3] = bc->body[bc->cur_pos + 3];
477 RETURN(INTVAL result);
481 /* Read a type token (32 bits, unsigned). */
482 METHOD INTVAL read_ttype()
485 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
486 char *val_ptr = (char *)&result;
488 /* Handle cases where we've an invalid PMC. */
490 real_exception(INTERP, NULL, E_StandardError,
491 "Invalid DotNetBytecode PMC");
493 /* Ensure we won't read past the end. */
494 if (bc->cur_pos + 3 >= bc->body_size)
495 real_exception(INTERP, NULL, E_StandardError,
496 "Read past end of bytecode");
498 /* Otherwise read the value. */
499 if (PARROT_BIGENDIAN)
501 val_ptr[3] = bc->body[bc->cur_pos];
502 val_ptr[2] = bc->body[bc->cur_pos + 1];
503 val_ptr[1] = bc->body[bc->cur_pos + 2];
504 val_ptr[0] = bc->body[bc->cur_pos + 3];
508 val_ptr[0] = bc->body[bc->cur_pos];
509 val_ptr[1] = bc->body[bc->cur_pos + 1];
510 val_ptr[2] = bc->body[bc->cur_pos + 2];
511 val_ptr[3] = bc->body[bc->cur_pos + 3];
515 RETURN(INTVAL result);
519 /* Read a string token (32 bits, unsigned). */
520 METHOD INTVAL read_tstring()
523 dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
524 char *val_ptr = (char *)&result;
526 /* Handle cases where we've an invalid PMC. */
528 real_exception(INTERP, NULL, E_StandardError,
529 "Invalid DotNetBytecode PMC");
531 /* Ensure we won't read past the end. */
532 if (bc->cur_pos + 3 >= bc->body_size)
533 real_exception(INTERP, NULL, E_StandardError,
534 "Read past end of bytecode");
536 /* Otherwise read the value. */
537 if (PARROT_BIGENDIAN)
539 val_ptr[3] = bc->body[bc->cur_pos];
540 val_ptr[2] = bc->body[bc->cur_pos + 1];
541 val_ptr[1] = bc->body[bc->cur_pos + 2];
542 val_ptr[0] = bc->body[bc->cur_pos + 3];
546 val_ptr[0] = bc->body[bc->cur_pos];
547 val_ptr[1] = bc->body[bc->cur_pos + 1];
548 val_ptr[2] = bc->body[bc->cur_pos + 2];
549 val_ptr[3] = bc->body[bc->cur_pos + 3];
552 RETURN(INTVAL result);
559 * c-file-style: "parrot"
561 * vim: expandtab shiftwidth=4: