Author: fperrad
Date: Wed May 7 00:37:52 2008
New Revision: 27374
Added:
trunk/languages/lua/src/pmc/luabytecode.pmc (contents, props changed)
Modified:
trunk/MANIFEST
trunk/languages/lua/config/makefiles/root.in
trunk/languages/lua/luad.pir
trunk/languages/lua/src/lib/luabytecode.pir
trunk/languages/lua/src/pmc/lua.pmc
Log:
[Lua]
- implement bytecode loader in a PMC
Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST (original)
+++ trunk/MANIFEST Wed May 7 00:37:52 2008
@@ -1,7 +1,7 @@
# ex: set ro:
# $Id$
#
-# generated by tools/dev/mk_manifest_and_skip.pl Mon May 5 23:32:49 2008 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Wed May 7 07:35:21 2008 UT
#
# See tools/dev/install_files.pl for documentation on the
# format of this file.
@@ -1618,6 +1618,7 @@
languages/lua/src/pmc/lua_private.h [lua]
languages/lua/src/pmc/luaany.pmc [lua]
languages/lua/src/pmc/luaboolean.pmc [lua]
+languages/lua/src/pmc/luabytecode.pmc [lua]
languages/lua/src/pmc/luaclosure.pmc [lua]
languages/lua/src/pmc/luafunction.pmc [lua]
languages/lua/src/pmc/luanil.pmc [lua]
Modified: trunk/languages/lua/config/makefiles/root.in
==============================================================================
--- trunk/languages/lua/config/makefiles/root.in (original)
+++ trunk/languages/lua/config/makefiles/root.in Wed May 7 00:37:52 2008
@@ -26,6 +26,7 @@
lua \
luaany \
luaboolean \
+ luabytecode \
luaclosure \
luafunction \
luanil \
@@ -39,6 +40,7 @@
$(PMCDIR)/lua.pmc \
$(PMCDIR)/luaany.pmc \
$(PMCDIR)/luaboolean.pmc \
+ $(PMCDIR)/luabytecode.pmc \
$(PMCDIR)/luaclosure.pmc \
$(PMCDIR)/luafunction.pmc \
$(PMCDIR)/luanil.pmc \
Modified: trunk/languages/lua/luad.pir
==============================================================================
--- trunk/languages/lua/luad.pir (original)
+++ trunk/languages/lua/luad.pir Wed May 7 00:37:52 2008
@@ -39,8 +39,8 @@
unless content goto L1
.local pmc script
push_eh _handler
- $P0 = get_hll_global ['Lua::Bytecode'], 'undump'
- script = $P0(content)
+ new $P0, 'LuaBytecode'
+ script = $P0.'undump'(content)
.local string basename
$P0 = split '/', filename
$S0 = pop $P0
Modified: trunk/languages/lua/src/lib/luabytecode.pir
==============================================================================
--- trunk/languages/lua/src/lib/luabytecode.pir (original)
+++ trunk/languages/lua/src/lib/luabytecode.pir Wed May 7 00:37:52 2008
@@ -53,78 +53,6 @@
$P0 = subclass 'String', 'Lua::Upvalue'
.end
-.sub 'undump'
- .param string bytecode
- .local int idx
- .local pmc script
- idx = 0
- $S0 = substr bytecode, idx, 4
- if $S0 == "\x1BLua" goto L1
- die "not a Lua bytecode"
- L1:
- idx += 4
- script = new 'Lua::Bytecode'
- $S0 = bytecode[idx]
- $I0 = ord $S0
- if $I0 == 0x51 goto L2
- die "only Lua 5.1 bytecode is supported"
- L2:
- new $P0, 'Integer'
- set $P0, $I0
- setattribute script, 'version', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute script, 'format', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Boolean'
- set $P0, $I0
- setattribute script, 'endian', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute script, 'sizeof_int', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute script, 'sizeof_size_t', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute script, 'sizeof_opcode', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute script, 'sizeof_number', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Boolean'
- set $P0, $I0
- setattribute script, 'integral', $P0
- idx += 1
- new $P0, 'Lua::Function'
- idx = $P0.'init'(script, bytecode, idx)
- setattribute script, 'top', $P0
- $I0 = length bytecode
- if idx == $I0 goto L3
- die "bad length"
- L3:
- .return (script)
-.end
-
.sub 'brief' :method
.param string filename
print "; source chunk: "
@@ -134,125 +62,9 @@
$P0.'brief'(0, 1)
.end
-.sub 'get_int' :method
- .param string str
- .local int endian
- $P0 = getattribute self, 'endian'
- endian = $P0
- .local int ret
- $P0 = split '', str
- ret = 0
- L1:
- unless $P0 goto L2
- unless endian goto L3
- $P1 = pop $P0
- goto L4
- L3:
- $P1 = shift $P0
- L4:
- $S1 = $P1
- $I0 = ord $S1
- ret <<= 8
- ret += $I0
- goto L1
- L2:
- .return (ret)
-.end
-
-.sub 'get_Integer' :method
- .param string str
- .local pmc ret
- $I0 = self.'get_int'(str)
- new ret, 'Integer'
- set ret, $I0
- .return (ret)
-.end
-
-.sub 'get_number' :method
- .param string str
- .local num ret
- new $P0, 'Lua'
- ret = $P0.'float_from_bytecode'(str)
-# ret = 0.0
- .return (ret)
-.end
-
.namespace ['Lua::Function']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size_t
- $P0 = getattribute script, 'sizeof_size_t'
- size_t = $P0
- $S0 = substr bytecode, idx, size_t
- $I0 = script.'get_int'($S0)
- idx += size_t
- unless $I0 goto L1
- $S0 = substr bytecode, idx, $I0
- new $P0, 'String'
- set $P0, $S0
- setattribute self, 'source', $P0
- idx += $I0
- L1:
- .local int size
- $P0 = getattribute script, 'sizeof_int'
- size = $P0
- $S0 = substr bytecode, idx, size
- $P0 = script.'get_Integer'($S0)
- setattribute self, 'linedefined', $P0
- idx += size
- $S0 = substr bytecode, idx, size
- $P0 = script.'get_Integer'($S0)
- setattribute self, 'lastlinedefined', $P0
- idx += size
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute self, 'nups', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute self, 'numparams', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute self, 'is_vararg', $P0
- idx += 1
- $S0 = bytecode[idx]
- $I0 = ord $S0
- new $P0, 'Integer'
- set $P0, $I0
- setattribute self, 'maxstacksize', $P0
- idx += 1
- $P0 = new 'Lua::InstructionList'
- idx = $P0.'init'(script, bytecode, idx)
- setattribute self, 'code', $P0
- $P0 = new 'Lua::ConstantList'
- idx = $P0.'init'(script, bytecode, idx)
- setattribute self, 'k', $P0
- $P0 = new 'Lua::PrototypeList'
- idx = $P0.'init'(script, bytecode, idx)
- setattribute self, 'p', $P0
- $P0 = new 'Lua::LineList'
- idx = $P0.'init'(script, bytecode, idx)
- setattribute self, 'lineinfo', $P0
- $P0 = new 'Lua::LocalList'
- idx = $P0.'init'(script, bytecode, idx)
- setattribute self, 'locvars', $P0
- $P0 = new 'Lua::UpvalueList'
- idx = $P0.'init'(script, bytecode, idx)
- setattribute self, 'upvalues', $P0
- .return (idx)
-.end
-
.sub 'brief' :method
.param int i
.param int level
@@ -303,87 +115,9 @@
print "; end of function\n\n"
.end
-.namespace ['Lua::InstructionList']
-
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size
- $P0 = getattribute script, 'sizeof_int'
- size = $P0
- .local int n
- $S0 = substr bytecode, idx, size
- n = script.'get_int'($S0)
- set self, n
- idx += size
- $P0 = getattribute script, 'sizeof_opcode'
- size = $P0
- .local int i
- i = 0
- L1:
- unless i < n goto L2
- $S0 = substr bytecode, idx, size
- $I0 = script.'get_int'($S0)
- self[i] = $I0
- idx += size
- inc i
- goto L1
- L2:
- .return (idx)
-.end
-
.namespace ['Lua::ConstantList']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size
- $P0 = getattribute script, 'sizeof_int'
- size = $P0
- .local int n
- $S0 = substr bytecode, idx, size
- n = script.'get_int'($S0)
- set self, n
- idx += size
- .local int i
- i = 0
- L1:
- unless i < n goto L2
- $S0 = bytecode[idx]
- $I0 = ord $S0
- idx += 1
- unless $I0 == 0 goto L3
- $P0 = new 'Lua::Nil'
- goto L9
- L3:
- unless $I0 == 1 goto L4
- $P0 = new 'Lua::Boolean'
- idx = $P0.'init'(script, bytecode, idx)
- goto L9
- L4:
- unless $I0 == 3 goto L5
- $P0 = new 'Lua::Number'
- idx = $P0.'init'(script, bytecode, idx)
- goto L9
- L5:
- unless $I0 == 4 goto L6
- $P0 = new 'Lua::String'
- idx = $P0.'init'(script, bytecode, idx)
- goto L9
- L6:
- $S0 = "invalid type of constant"
- die $S0
- L9:
- self[i] = $P0
- inc i
- goto L1
- L2:
- .return (idx)
-.end
-
.sub 'brief' :method
.local int i, n
n = self
@@ -410,16 +144,6 @@
.namespace ['Lua::Boolean']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- $S0 = bytecode[idx]
- $I0 = ord $S0
- set self, $I0
- .return (idx)
-.end
-
.sub 'brief' :method
.param int i
print ".const "
@@ -432,20 +156,6 @@
.namespace ['Lua::Number']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size
- $P0 = getattribute script, 'sizeof_number'
- size = $P0
- $S0 = substr bytecode, idx, size
- $N0 = script.'get_number'($S0)
- idx += size
- set self, $N0
- .return (idx)
-.end
-
.sub 'brief' :method
.param int i
print ".const "
@@ -458,27 +168,6 @@
.namespace ['Lua::String']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size_t
- $P0 = getattribute script, 'sizeof_size_t'
- size_t = $P0
- $S0 = substr bytecode, idx, size_t
- $I0 = script.'get_int'($S0)
- idx += size_t
- $S0 = ''
- unless $I0 goto L1
- $S0 = substr bytecode, idx, $I0
- idx += $I0
- dec $I0
- $S0 = substr $S0, 0, $I0
- L1:
- set self, $S0
- .return (idx)
-.end
-
.sub 'brief' :method
.param int i
print ".const \""
@@ -493,31 +182,6 @@
.namespace ['Lua::PrototypeList']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size
- $P0 = getattribute script, 'sizeof_int'
- size = $P0
- .local int n
- $S0 = substr bytecode, idx, size
- n = script.'get_int'($S0)
- set self, n
- idx += size
- .local int i
- i = 0
- L1:
- unless i < n goto L2
- new $P0, 'Lua::Function'
- idx = $P0.'init'(script, bytecode, idx)
- self[i] = $P0
- inc i
- goto L1
- L2:
- .return (idx)
-.end
-
.sub 'brief' :method
.param int level
.local int i, n
@@ -533,62 +197,8 @@
.end
-.namespace ['Lua::LineList']
-
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size
- $P0 = getattribute script, 'sizeof_int'
- size = $P0
- .local int n
- $S0 = substr bytecode, idx, size
- n = script.'get_int'($S0)
- set self, n
- idx += size
- .local int i
- i = 0
- L1:
- unless i < n goto L2
- $S0 = substr bytecode, idx, size
- $P0 = script.'get_Integer'($S0)
- idx += size
- self[i] = $P0
- inc i
- goto L1
- L2:
- .return (idx)
-.end
-
-
.namespace ['Lua::LocalList']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size
- $P0 = getattribute script, 'sizeof_int'
- size = $P0
- .local int n
- $S0 = substr bytecode, idx, size
- n = script.'get_int'($S0)
- set self, n
- idx += size
- .local int i
- i = 0
- L1:
- unless i < n goto L2
- new $P0, 'Lua::Local'
- idx = $P0.'init'(script, bytecode, idx)
- self[i] = $P0
- inc i
- goto L1
- L2:
- .return (idx)
-.end
-
.sub 'brief' :method
.local int i, n
n = self
@@ -605,38 +215,6 @@
.namespace ['Lua::Local']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size_t
- $P0 = getattribute script, 'sizeof_size_t'
- size_t = $P0
- $S0 = substr bytecode, idx, size_t
- $I0 = script.'get_int'($S0)
- idx += size_t
- $S0 = ''
- unless $I0 goto L1
- $S0 = substr bytecode, idx, $I0
- idx += $I0
- dec $I0
- $S0 = substr $S0, 0, $I0
- L1:
- set self, $S0
- .local int size
- $P0 = getattribute script, 'sizeof_int'
- size = $P0
- $S0 = substr bytecode, idx, size
- $P0 = script.'get_Integer'($S0)
- setattribute self, 'startpc', $P0
- idx += size
- $S0 = substr bytecode, idx, size
- $P0 = script.'get_Integer'($S0)
- setattribute self, 'endpc', $P0
- idx += size
- .return (idx)
-.end
-
.sub 'brief' :method
.param int i
print ".local \""
@@ -649,31 +227,6 @@
.namespace ['Lua::UpvalueList']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size
- $P0 = getattribute script, 'sizeof_int'
- size = $P0
- .local int n
- $S0 = substr bytecode, idx, size
- n = script.'get_int'($S0)
- set self, n
- idx += size
- .local int i
- i = 0
- L1:
- unless i < n goto L2
- new $P0, 'Lua::Upvalue'
- idx = $P0.'init'(script, bytecode, idx)
- self[i] = $P0
- inc i
- goto L1
- L2:
- .return (idx)
-.end
-
.sub 'brief' :method
.local int i, n
n = self
@@ -690,27 +243,6 @@
.namespace ['Lua::Upvalue']
-.sub 'init' :method
- .param pmc script
- .param string bytecode
- .param int idx
- .local int size_t
- $P0 = getattribute script, 'sizeof_size_t'
- size_t = $P0
- $S0 = substr bytecode, idx, size_t
- $I0 = script.'get_int'($S0)
- idx += size_t
- $S0 = ''
- unless $I0 goto L1
- $S0 = substr bytecode, idx, $I0
- idx += $I0
- dec $I0
- $S0 = substr $S0, 0, $I0
- L1:
- set self, $S0
- .return (idx)
-.end
-
.sub 'brief' :method
.param int i
print ".upvalue \""
Modified: trunk/languages/lua/src/pmc/lua.pmc
==============================================================================
--- trunk/languages/lua/src/pmc/lua.pmc (original)
+++ trunk/languages/lua/src/pmc/lua.pmc Wed May 7 00:37:52 2008
@@ -435,12 +435,6 @@
RETURN(STRING *retval);
}
- METHOD FLOATVAL float_from_bytecode(STRING *str) {
- FLOATVAL retval;
- memcpy(&retval, str->strstart, sizeof retval);
- RETURN(FLOATVAL retval);
- }
-
}
/*
Added: trunk/languages/lua/src/pmc/luabytecode.pmc
==============================================================================
--- (empty file)
+++ trunk/languages/lua/src/pmc/luabytecode.pmc Wed May 7 00:37:52 2008
@@ -0,0 +1,415 @@
+/*
+Copyright (C) 2008, The Perl Foundation.
+$Id$
+
+=head1 NAME
+
+pmc/luabytecode - Lua 5.1 VM bytecode loader
+
+=head1 DESCRIPTION
+
+This singleton PMC holds a factory.
+
+=head2 Methods
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/embed.h"
+
+/*** from lua.h ***/
+
+/* type of numbers in Lua */
+typedef double lua_Number;
+
+/*** from limits.h ***/
+
+/*
+** type for virtual-machine instructions
+** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
+*/
+typedef Parrot_Int4 Instruction;
+
+/*** from lundump.h ***/
+
+/* for header of binary files -- this is Lua 5.1 */
+#define LUAC_VERSION 0x51
+
+/* for header of binary files -- this is the official format */
+#define LUAC_FORMAT 0
+
+/* size of header of binary files */
+#define LUAC_HEADERSIZE 12
+
+/*** ***/
+
+static const char header_ref[LUAC_HEADERSIZE] = {
+ '\033', 'L', 'u', 'a',
+ LUAC_VERSION,
+ LUAC_FORMAT,
+ PARROT_LITTLEENDIAN,
+ sizeof(int),
+ sizeof(size_t),
+ sizeof(Instruction),
+ sizeof(lua_Number),
+ 0,
+};
+
+static PMC * LuaBytecode_PMC;
+static PMC * script;
+static const char * bytecode;
+static UINTVAL maxi;
+static const char *fp;
+
+static void _init(Interp *interp, STRING *str)
+{
+ bytecode = Parrot_string_cstring(interp, str);
+ maxi = string_length(interp, str);
+ fp = (const char *)bytecode;
+}
+
+
+#define _info_get() (UINTVAL)(&bytecode[maxi] - fp)
+#define _get_pos() (fp)
+#define _get_byte() (*(fp++))
+
+static void _get_block(void* b, size_t size)
+{
+ memcpy(b, fp, size);
+ fp += size;
+}
+
+static int _get_integer()
+{
+ int x;
+ memcpy(&x, fp, sizeof x);
+ fp += sizeof x;
+ return x;
+}
+
+static Instruction _get_instruction()
+{
+ Instruction x;
+ memcpy(&x, fp, sizeof x);
+ fp += sizeof x;
+ return x;
+}
+
+static double _get_number()
+{
+ double x;
+ memcpy(&x, fp, sizeof x);
+ fp += sizeof x;
+ return x;
+}
+
+static STRING* _get_string(Interp *interp)
+{
+ STRING* str;
+ size_t s;
+ memcpy(&s, fp, sizeof s);
+ fp += sizeof s;
+ if (s != 0) {
+ str = string_from_cstring(interp, fp, s-1);
+ fp += s;
+ }
+ else
+ str = string_from_cstring(interp, "", 0);
+ return str;
+}
+
+static PMC* _load_function(Interp *interp);
+
+static PMC* _load_bool(Interp *interp)
+{
+ PMC* ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Boolean")));
+ VTABLE_set_integer_native(interp, ret, _get_byte());
+ return ret;
+}
+
+static PMC* _load_byte(Interp *interp)
+{
+ PMC* ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Integer")));
+ VTABLE_set_integer_native(interp, ret, _get_byte());
+ return ret;
+}
+
+static PMC* _load_integer(Interp *interp)
+{
+ PMC* ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Integer")));
+ VTABLE_set_integer_native(interp, ret, _get_integer());
+ return ret;
+}
+
+static PMC* _load_string(Interp *interp)
+{
+ PMC* ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "String")));
+ VTABLE_set_string_native(interp, ret, _get_string(interp));
+ return ret;
+}
+
+static void _load_header(Interp *interp)
+{
+ char header[LUAC_HEADERSIZE];
+
+ _get_block(header, sizeof header);
+ if (memcmp(header, header_ref, sizeof header) != 0) {
+ real_exception(interp, NULL, ILL_INHERIT,
+ "bad header");
+ }
+#if 1
+ fp -= 8;
+ VTABLE_set_attr_str(interp, script,
+ const_string(interp, "version"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, script,
+ const_string(interp, "format"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, script,
+ const_string(interp, "endian"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, script,
+ const_string(interp, "sizeof_int"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, script,
+ const_string(interp, "sizeof_size_t"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, script,
+ const_string(interp, "sizeof_opcode"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, script,
+ const_string(interp, "sizeof_number"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, script,
+ const_string(interp, "integral"), _load_byte(interp));
+#endif
+}
+
+static PMC* _load_instruction_list(Interp *interp)
+{
+ int i;
+ int n = _get_integer();
+ PMC * ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::InstructionList")));
+ VTABLE_set_integer_native(interp, ret, n);
+
+ for (i = 0; i < n; i++) {
+ VTABLE_set_integer_keyed_int(interp, ret, i, _get_instruction());
+ }
+
+ return ret;
+}
+
+static PMC* _load_constant_list(Interp *interp)
+{
+ int i;
+ int n = _get_integer();
+ PMC * ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::ConstantList")));
+ VTABLE_set_integer_native(interp, ret, n);
+
+ for (i = 0; i < n; i++) {
+ PMC* k;
+ int type = _get_byte();
+ switch (type) {
+ case 0:
+ k = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::Nil")));
+ break;
+ case 1:
+ k = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::Boolean")));
+ VTABLE_set_integer_native(interp, k, _get_byte());
+ break;
+ case 3:
+ k = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::Number")));
+ VTABLE_set_number_native(interp, k, _get_number());
+ break;
+ case 4:
+ k = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::String")));
+ VTABLE_set_string_native(interp, k, _get_string(interp));
+ break;
+ default:
+ real_exception(interp, NULL, ILL_INHERIT,
+ "bad constant");
+ }
+ VTABLE_set_pmc_keyed_int(interp, ret, i, k);
+ }
+
+ return ret;
+}
+
+static PMC* _load_prototype_list(Interp *interp)
+{
+ int i;
+ int n = _get_integer();
+ PMC * ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::PrototypeList")));
+ VTABLE_set_integer_native(interp, ret, n);
+
+ for (i = 0; i < n; i++) {
+ VTABLE_set_pmc_keyed_int(interp, ret, i, _load_function(interp));
+ }
+
+ return ret;
+}
+
+static PMC* _load_line_list(Interp *interp)
+{
+ int i;
+ int n = _get_integer();
+ PMC * ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::LineList")));
+ VTABLE_set_integer_native(interp, ret, n);
+
+ for (i = 0; i < n; i++) {
+ VTABLE_set_integer_keyed_int(interp, ret, i, _get_integer());
+ }
+
+ return ret;
+}
+
+static PMC* _load_local_list(Interp *interp)
+{
+ int i;
+ int n = _get_integer();
+ PMC * ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::LocalList")));
+ VTABLE_set_integer_native(interp, ret, n);
+
+ for (i = 0; i < n; i++) {
+ PMC* local = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::Local")));
+ VTABLE_set_string_native(interp, local, _get_string(interp));
+ VTABLE_set_attr_str(interp, local,
+ const_string(interp, "startpc"), _load_integer(interp));
+ VTABLE_set_attr_str(interp, local,
+ const_string(interp, "endpc"), _load_integer(interp));
+ VTABLE_set_pmc_keyed_int(interp, ret, i, local);
+ }
+
+ return ret;
+}
+
+static PMC* _load_upvalue_list(Interp *interp)
+{
+ int i;
+ int n = _get_integer();
+ PMC * ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::UpvalueList")));
+ VTABLE_set_integer_native(interp, ret, n);
+
+ for (i = 0; i < n; i++) {
+ PMC* upvalue = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::Upvalue")));
+ VTABLE_set_string_native(interp, upvalue, _get_string(interp));
+ VTABLE_set_pmc_keyed_int(interp, ret, i, upvalue);
+ }
+
+ return ret;
+}
+
+static PMC* _load_function(Interp *interp)
+{
+ PMC * ret = pmc_new(interp, pmc_type(interp,
+ const_string(interp, "Lua::Function")));
+
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "source"), _load_string(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "linedefined"), _load_integer(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "lastlinedefined"), _load_integer(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "nups"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "numparams"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "is_vararg"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "maxstacksize"), _load_byte(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "code"), _load_instruction_list(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "k"), _load_constant_list(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "p"), _load_prototype_list(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "lineinfo"), _load_line_list(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "locvars"), _load_local_list(interp));
+ VTABLE_set_attr_str(interp, ret,
+ const_string(interp, "upvalues"), _load_upvalue_list(interp));
+
+ return ret;
+}
+
+
+pmclass LuaBytecode
+ singleton
+ dynpmc
+ group lua_group {
+
+/*
+
+=item C<void* get_pointer()>
+
+=item C<void set_pointer(void *ptr)>
+
+These two functions are part of the singleton creation interface. For more
+information see F<src/pmc.c>.
+
+=cut
+
+*/
+ void* get_pointer() {
+ return LuaBytecode_PMC;
+ }
+
+ void set_pointer(void* ptr) {
+ LuaBytecode_PMC = (PMC*) ptr;
+ }
+
+/*
+
+=item C<PMC* undump(STRING* bytecode)>
+
+Loads Lua 5.1 VM bytecode.
+
+=cut
+
+*/
+ METHOD PMC* undump(STRING* bytecode) {
+ script = pmc_new(INTERP, pmc_type(INTERP,
+ const_string(INTERP, "Lua::Bytecode")));
+
+ _init(INTERP, bytecode);
+ _load_header(INTERP);
+ VTABLE_set_attr_str(INTERP, script,
+ const_string(interp, "top"), _load_function(INTERP));
+
+ RETURN(PMC *script);
+ }
+
+}
+
+/*
+
+=back
+
+=head1 AUTHORS
+
+Francois Perrad
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */