2 Copyright (C) 2006-2008, The Perl Foundation.
7 pmc/wmlsbytecode - WMLScript bytecode loader
11 This singleton PMC holds a factory.
21 #include "parrot/embed.h"
23 static PMC * WmlsBytecode_PMC;
25 static const char * bytecode;
27 static const char *fp;
29 static void _init(Interp *interp, STRING *str)
31 bytecode = Parrot_string_cstring(interp, str);
32 maxi = string_length(interp, str);
33 fp = (const char *)bytecode;
36 #define _info_get() (UINTVAL)(&bytecode[maxi] - fp)
37 #define _get_pos() (fp)
38 #define _get_c() (*(fp++))
40 static unsigned short _get_mb16(void)
56 static unsigned int _get_mb32(void)
72 static unsigned char _get_uint8(void)
77 static unsigned short _get_uint16(void)
90 static char _get_int8(void)
92 return (char)_get_c();
95 static short _get_int16(void)
108 static int _get_int32(void)
127 static float _get_float32(void)
130 unsigned char *ptr = (unsigned char *)&value;
147 static int _load_header(Interp *interp)
149 UINTVAL VersionNumber;
152 VersionNumber = _get_uint8();
154 if (VersionNumber != 0x01)
155 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ILL_INHERIT,
156 "incorrect version");
158 VTABLE_set_integer_keyed_str(interp, script,
159 const_string(interp, "VersionNumber"), VersionNumber);
161 CodeSize = _get_mb32();
163 if (CodeSize != _info_get())
164 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ILL_INHERIT,
165 "incorrect code size");
167 VTABLE_set_integer_keyed_str(interp, script,
168 const_string(interp, "CodeSize"), CodeSize);
173 static int _load_constant_pool(Interp *interp)
175 UINTVAL NumberOfConstants;
176 UINTVAL CharacterSet;
180 NumberOfConstants = _get_mb16();
181 Constants = pmc_new(interp, pmc_type(interp,
182 const_string(interp, "Wmls::Constants")));
183 VTABLE_set_integer_native(interp, Constants, NumberOfConstants);
184 VTABLE_set_pmc_keyed_str(interp, script,
185 const_string(interp, "Constants"), Constants);
187 CharacterSet = _get_mb16();
188 VTABLE_set_integer_keyed_str(interp, script,
189 const_string(interp, "CharacterSet"), CharacterSet);
191 for (idx = 0; idx < NumberOfConstants; idx++) {
193 UINTVAL ConstantType = _get_uint8();
194 switch (ConstantType) {
197 INTVAL ConstantInteger8 = _get_int8();
198 Constant = pmc_new(interp, pmc_type(interp,
199 const_string(interp, "Wmls::ConstantInteger")));
200 VTABLE_set_integer_native(interp, Constant, ConstantInteger8);
205 INTVAL ConstantInteger16 = _get_int16();
206 Constant = pmc_new(interp, pmc_type(interp,
207 const_string(interp, "Wmls::ConstantInteger")));
208 VTABLE_set_integer_native(interp, Constant, ConstantInteger16);
213 INTVAL ConstantInteger32 = _get_int32();
214 Constant = pmc_new(interp, pmc_type(interp,
215 const_string(interp, "Wmls::ConstantInteger")));
216 VTABLE_set_integer_native(interp, Constant, ConstantInteger32);
221 FLOATVAL ConstantFloat32 = _get_float32();
222 Constant = pmc_new(interp, pmc_type(interp,
223 const_string(interp, "Wmls::ConstantFloat")));
224 VTABLE_set_number_native(interp, Constant, ConstantFloat32);
229 UINTVAL StringSize = _get_mb32();
230 STRING * String = string_make(interp, _get_pos(),
231 StringSize, "unicode", 0);
232 while (StringSize --) {
235 Constant = pmc_new(interp, pmc_type(interp,
236 const_string(interp, "Wmls::ConstantUTF8String")));
237 VTABLE_set_string_native(interp, Constant, String);
242 Constant = pmc_new(interp, pmc_type(interp,
243 const_string(interp, "Wmls::ConstantEmptyString")));
248 UINTVAL StringSize = _get_mb32();
249 STRING * String = string_from_cstring(interp,
250 _get_pos(), StringSize);
251 while (StringSize --) {
254 Constant = pmc_new(interp, pmc_type(interp,
255 const_string(interp, "Wmls::ConstantString")));
256 VTABLE_set_string_native(interp, Constant, String);
260 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ILL_INHERIT,
261 "invalid ConstantType (%u).", ConstantType);
263 VTABLE_set_pmc_keyed_int(interp, Constants, idx, Constant);
269 static int _load_pragma_pool(Interp *interp)
271 UINTVAL NumberOfPragmas;
275 NumberOfPragmas = _get_mb16();
276 Pragmas = pmc_new(interp, pmc_type(interp,
277 const_string(interp, "Wmls::Pragmas")));
278 VTABLE_set_integer_native(interp, Pragmas, NumberOfPragmas);
279 VTABLE_set_pmc_keyed_str(interp, script,
280 const_string(interp, "Pragmas"), Pragmas);
282 for (idx = 0; idx < NumberOfPragmas; idx++) {
284 UINTVAL PragmaType = _get_uint8();
285 switch (PragmaType) {
288 UINTVAL AccessDomainIndex = _get_mb16();
289 Pragma = pmc_new(interp, pmc_type(interp,
290 const_string(interp, "Wmls::AccessDomain")));
291 VTABLE_set_integer_keyed_str(interp, Pragma,
292 const_string(interp, "AccessDomainIndex"), AccessDomainIndex);
297 UINTVAL AccessPathIndex = _get_mb16();
298 Pragma = pmc_new(interp, pmc_type(interp,
299 const_string(interp, "Wmls::AccessPath")));
300 VTABLE_set_integer_keyed_str(interp, Pragma,
301 const_string(interp, "AccessPathIndex"), AccessPathIndex);
306 UINTVAL PropertyNameIndex = _get_mb16();
307 UINTVAL ContentIndex = _get_mb16();
308 Pragma = pmc_new(interp, pmc_type(interp,
309 const_string(interp, "Wmls::UserAgentProperty")));
310 VTABLE_set_integer_keyed_str(interp, Pragma,
311 const_string(interp, "PropertyNameIndex"), PropertyNameIndex);
312 VTABLE_set_integer_keyed_str(interp, Pragma,
313 const_string(interp, "ContentIndex"), ContentIndex);
318 UINTVAL PropertyNameIndex = _get_mb16();
319 UINTVAL ContentIndex = _get_mb16();
320 UINTVAL SchemeIndex = _get_mb16();
321 Pragma = pmc_new(interp, pmc_type(interp,
322 const_string(interp, "Wmls::UserAgentProperty&Scheme")));
323 VTABLE_set_integer_keyed_str(interp, Pragma,
324 const_string(interp, "PropertyNameIndex"), PropertyNameIndex);
325 VTABLE_set_integer_keyed_str(interp, Pragma,
326 const_string(interp, "ContentIndex"), ContentIndex);
327 VTABLE_set_integer_keyed_str(interp, Pragma,
328 const_string(interp, "SchemeIndex"), SchemeIndex);
332 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ILL_INHERIT,
333 "invalid PragmaType (%u).", PragmaType);
335 VTABLE_set_pmc_keyed_int(interp, Pragmas, idx, Pragma);
341 static int _load_function_pool(Interp *interp)
343 UINTVAL NumberOfFunctions;
344 UINTVAL NumberOfFunctionNames;
347 PMC * FunctionNameTable;
349 NumberOfFunctions = _get_uint8();
350 Functions = pmc_new(interp, pmc_type(interp,
351 const_string(interp, "Wmls::Functions")));
352 VTABLE_set_integer_native(interp, Functions, NumberOfFunctions);
353 VTABLE_set_pmc_keyed_str(interp, script,
354 const_string(interp, "Functions"), Functions);
356 NumberOfFunctionNames = _get_uint8();
357 FunctionNameTable = pmc_new(interp, pmc_type(interp,
358 const_string(interp, "Wmls::FunctionNameTable")));
359 VTABLE_set_integer_native(interp, FunctionNameTable,
360 NumberOfFunctionNames);
361 VTABLE_set_pmc_keyed_str(interp, script,
362 const_string(interp, "FunctionNameTable"), FunctionNameTable);
364 for (idx = 0; idx < NumberOfFunctionNames; idx++) {
365 PMC * Couple = pmc_new(interp, enum_class_Array);
366 UINTVAL FunctionIndex = _get_uint8();
367 UINTVAL FunctionNameSize = _get_uint8();
368 STRING * FunctionName = string_make(interp, _get_pos(),
369 FunctionNameSize, "unicode", 0);
370 while (FunctionNameSize --) {
373 VTABLE_set_integer_native(interp, Couple, 2);
374 VTABLE_set_integer_keyed_int(interp, Couple, 0, FunctionIndex);
375 VTABLE_set_string_keyed_int(interp, Couple, 1, FunctionName);
377 VTABLE_set_pmc_keyed_int(interp, FunctionNameTable, idx, Couple);
380 for (idx = 0; idx < NumberOfFunctions; idx++) {
382 UINTVAL NumberOfArguments = _get_uint8();
383 UINTVAL NumberOfLocalVariables = _get_uint8();
384 UINTVAL FunctionSize = _get_mb32();
385 STRING * CodeArray = string_make(interp, _get_pos(),
386 FunctionSize, "binary", 0);
387 while (FunctionSize --) {
390 Function = pmc_new(interp, pmc_type(interp,
391 const_string(interp, "Wmls::Function")));
392 VTABLE_set_integer_keyed_str(interp, Function,
393 const_string(interp, "NumberOfArguments"), NumberOfArguments);
394 VTABLE_set_integer_keyed_str(interp, Function,
395 const_string(interp, "NumberOfLocalVariables"),
396 NumberOfLocalVariables);
397 VTABLE_set_string_keyed_str(interp, Function,
398 const_string(interp, "CodeArray"), CodeArray);
400 VTABLE_set_pmc_keyed_int(interp, Functions, idx, Function);
403 if (_info_get() != 0)
404 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ILL_INHERIT,
418 =item C<void* get_pointer()>
420 =item C<void set_pointer(void *ptr)>
422 These two functions are part of the singleton creation interface. For more
423 information see F<src/pmc.c>.
428 void* get_pointer() {
429 return WmlsBytecode_PMC;
432 void set_pointer(void* ptr) {
433 WmlsBytecode_PMC = (PMC*) ptr;
438 =item C<PMC* load(STRING* bytecode)>
440 Loads WMLScript bytecode.
445 METHOD PMC* load(STRING* bytecode) {
446 script = pmc_new(INTERP, pmc_type(INTERP,
447 const_string(INTERP, "Wmls::Script")));
448 _init(INTERP, bytecode);
449 if (_load_header(INTERP))
451 if (_load_constant_pool(INTERP))
453 if (_load_pragma_pool(INTERP))
455 if (_load_function_pool(INTERP))
478 * c-file-style: "parrot"
480 * vim: expandtab shiftwidth=4: