tagged release 0.6.4
[parrot.git] / languages / dotnet / pmc / dotnetbytecode.pmc
blob2144f55f6b7ef88579194e6263b50c68753ba247
1 /*
2  * $Id$
3  * Copyright (C) 2006-2008, The Perl Foundation.
4  */
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. */
17     void init()
18     {
19         PObj_custom_mark_SET(SELF);
20         PObj_active_destroy_SET(SELF);
21     }
24     /* Garbage Collection mark routine. */
25     void mark()
26     {
27         /* Tell the GC about stuff we're holding on to. */
28         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
29         if (bc->parent)
30             pobject_lives(INTERP, (PObj *)bc->parent);
31         if (bc->eh)
32             pobject_lives(INTERP, (PObj *)bc->eh);
33     }
36     /* Destructor. */
37     void destroy()
38     {
39         /* Cleanup any memory we're using. */
40         if (PMC_struct_val(SELF)) {
41             dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
42             if (bc->body)
43                 mem_sys_free(bc->body);
44             mem_sys_free(bc);
45             PMC_struct_val(SELF) = NULL;
46         }
47     }
50     /* Get local variables signature blob location. */
51     METHOD INTVAL get_locals_sig()
52     {
53         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
54         INTVAL           result;
56         /* Handle cases where we've an invalid PMC. */
57         if (!bc)
58             real_exception(INTERP, NULL, E_StandardError,
59                "Invalid DotNetBytecode PMC");
61         result = (INTVAL)bc->locals_signature;
62         RETURN(INTVAL result);
63     }
66     /* Initialize local variables flag. */
67     METHOD INTVAL init_locals()
68     {
69         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
70         INTVAL           result;
72         /* Handle cases where we've an invalid PMC. */
73         if (!bc)
74             real_exception(INTERP, NULL, E_StandardError,
75                "Invalid DotNetBytecode PMC");
77         result = bc->init_locals_flag;
78         RETURN(INTVAL result);
79     }
82     /* Get length of bytecode. */
83     METHOD INTVAL get_length()
84     {
85         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
86         INTVAL           result;
88         /* Handle cases where we've an invalid PMC. */
89         if (!bc)
90             real_exception(INTERP, NULL, E_StandardError,
91                "Invalid DotNetBytecode PMC");
93         result = bc->body_size;
94         RETURN(INTVAL result);
95     }
98     /* Get current bytecode position, for when walking bytecode. */
99     METHOD INTVAL get_pos()
100     {
101         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
102         INTVAL           result;
104         /* Handle cases where we've an invalid PMC. */
105         if (!bc)
106             real_exception(INTERP, NULL, E_StandardError,
107                "Invalid DotNetBytecode PMC");
109         result = bc->cur_pos;
110         RETURN(INTVAL result);
111     }
114     /* Set current bytecode position, for when walking bytecode. */
115     METHOD void set_pos(INTVAL pos)
116     {
117         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
119         /* Handle cases where we've an invalid PMC. */
120         if (!bc)
121             real_exception(INTERP, NULL, E_StandardError,
122                "Invalid DotNetBytecode PMC");
123         else
124             bc->cur_pos = pos;
125     }
128     /* Get error handlers PMC array. */
129     METHOD PMC* get_eh()
130     {
131         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
132         PMC             *result;
134         /* Handle cases where we've an invalid PMC. */
135         if (!bc)
136             real_exception(INTERP, NULL, E_StandardError,
137                "Invalid DotNetBytecode PMC");
139         result = bc->eh;
140         RETURN(PMC *result);
141     }
144     /* Read a signed 8-bit integer. */
145     METHOD INTVAL read_int8()
146     {
147         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
148         INTVAL           result;
150         /* Handle cases where we've an invalid PMC. */
151         if (!bc)
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];
162         bc->cur_pos++;
163         RETURN(INTVAL result);
164     }
167     /* Read an unsigned 8-bit integer. */
168     METHOD INTVAL read_uint8()
169     {
170         dotnet_bytecode *bc = (dotnet_bytecode *)PMC_struct_val(SELF);
171         INTVAL           result;
173         /* Handle cases where we've an invalid PMC. */
174         if (!bc)
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];
185         bc->cur_pos++;
186         RETURN(INTVAL result);
187     }
190     /* Read a signed 16-bit integer. */
191     METHOD INTVAL read_int16()
192     {
193         INTVAL           result;
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. */
198         if (!bc)
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)
209         {
210             val_ptr[1] = bc->body[bc->cur_pos];
211             val_ptr[0] = bc->body[bc->cur_pos + 1];
212         }
213         else
214         {
215             val_ptr[0] = bc->body[bc->cur_pos];
216             val_ptr[1] = bc->body[bc->cur_pos + 1];
217         }
218         bc->cur_pos += 2;
219         RETURN(INTVAL result);
220     }
223     /* Read an unsigned 16-bit integer. */
224     METHOD INTVAL read_uint16()
225     {
226         INTVAL           result;
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. */
231         if (!bc)
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)
242         {
243             val_ptr[1] = bc->body[bc->cur_pos];
244             val_ptr[0] = bc->body[bc->cur_pos + 1];
245         }
246         else
247         {
248             val_ptr[0] = bc->body[bc->cur_pos];
249             val_ptr[1] = bc->body[bc->cur_pos + 1];
250         }
251         bc->cur_pos += 2;
252         RETURN(INTVAL result);
253     }
256     /* Read a signed 32-bit integer. */
257     METHOD INTVAL read_int32()
258     {
259         INTVAL           result;
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. */
264         if (!bc)
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)
275         {
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];
280         }
281         else
282         {
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];
287         }
288         bc->cur_pos += 4;
289         RETURN(INTVAL result);
290     }
293     /* Read an unsigned 32-bit integer. */
294     METHOD INTVAL read_uint32()
295     {
296         INTVAL           result;
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. */
301         if (!bc)
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)
312         {
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];
317         }
318         else
319         {
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];
324         }
325         bc->cur_pos += 4;
326         RETURN(INTVAL result);
327     }
330     /* Read a 32-bit (single precision) floating pointer number. */
331     METHOD FLOATVAL read_float32()
332     {
333         FLOATVAL         result;
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. */
338         if (!bc)
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)
349         {
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];
354         }
355         else
356         {
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];
361         }
362         bc->cur_pos += 4;
363         RETURN(FLOATVAL result);
364     }
367     /* Read a 64-bit (double precision) floating pointer number. */
368     METHOD FLOATVAL read_float64()
369     {
370         int              i;
371         FLOATVAL         result;
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. */
376         if (!bc)
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)
388             {
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];
393             }
394             else
395             {
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];
400             }
401         }
402         bc->cur_pos += 8;
403         RETURN(FLOATVAL result);
404     }
407     /* Read a field token (32 bits, unsigned). */
408     METHOD INTVAL read_tfield()
409     {
410         INTVAL           result;
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. */
415         if (!bc)
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)
426         {
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];
431         }
432         else
433         {
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];
438         }
439         bc->cur_pos += 4;
440         RETURN(INTVAL result);
441     }
444     /* Read a method token (32 bits, unsigned). */
445     METHOD INTVAL read_tmethod()
446     {
447         INTVAL           result;
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. */
452         if (!bc)
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)
463         {
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];
468         }
469         else
470         {
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];
475         }
476         bc->cur_pos += 4;
477         RETURN(INTVAL result);
478     }
481     /* Read a type token (32 bits, unsigned). */
482     METHOD INTVAL read_ttype()
483     {
484         INTVAL           result;
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. */
489         if (!bc)
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)
500         {
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];
505         }
506         else
507         {
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];
512         }
514         bc->cur_pos += 4;
515         RETURN(INTVAL result);
516     }
519     /* Read a string token (32 bits, unsigned). */
520     METHOD INTVAL read_tstring()
521     {
522         INTVAL           result;
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. */
527         if (!bc)
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)
538         {
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];
543         }
544         else
545         {
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];
550         }
551         bc->cur_pos += 4;
552         RETURN(INTVAL result);
553     }
558  * Local variables:
559  *   c-file-style: "parrot"
560  * End:
561  * vim: expandtab shiftwidth=4:
562  */