Skip to content

Instantly share code, notes, and snippets.

@vuonghv
Created November 4, 2016 07:44
Show Gist options
  • Save vuonghv/44dc334f3e116e32cc58d7a18b921fc3 to your computer and use it in GitHub Desktop.
Save vuonghv/44dc334f3e116e32cc58d7a18b921fc3 to your computer and use it in GitHub Desktop.
Defining New Types using Python's C API
/*
* pydasm -- Python module wrapping libdasm
* 2016 Vuong Hoang <vuonghv.cs@gmail.com>
*/
#include <Python.h>
#include <structmember.h>
#include "../libdasm.h"
#define INSTRUCTION_STR_BUFFER_LENGTH 256
// Support Python 2.5
#ifndef PyVarObject_HEAD_INIT
#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
#endif
#ifndef Py_TYPE
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif
/*
* Instruction types borrowed from "libdasm.h"
*/
char *instruction_types[] = {
"INSTRUCTION_TYPE_ASC",
"INSTRUCTION_TYPE_DCL",
"INSTRUCTION_TYPE_MOV",
"INSTRUCTION_TYPE_MOVSR",
"INSTRUCTION_TYPE_ADD",
"INSTRUCTION_TYPE_XADD",
"INSTRUCTION_TYPE_ADC",
"INSTRUCTION_TYPE_SUB",
"INSTRUCTION_TYPE_SBB",
"INSTRUCTION_TYPE_INC",
"INSTRUCTION_TYPE_DEC",
"INSTRUCTION_TYPE_DIV",
"INSTRUCTION_TYPE_IDIV",
"INSTRUCTION_TYPE_NOT",
"INSTRUCTION_TYPE_NEG",
"INSTRUCTION_TYPE_STOS",
"INSTRUCTION_TYPE_LODS",
"INSTRUCTION_TYPE_SCAS",
"INSTRUCTION_TYPE_MOVS",
"INSTRUCTION_TYPE_MOVSX",
"INSTRUCTION_TYPE_MOVZX",
"INSTRUCTION_TYPE_CMPS",
"INSTRUCTION_TYPE_SHX",
"INSTRUCTION_TYPE_ROX",
"INSTRUCTION_TYPE_MUL",
"INSTRUCTION_TYPE_IMUL",
"INSTRUCTION_TYPE_EIMUL",
"INSTRUCTION_TYPE_XOR",
"INSTRUCTION_TYPE_LEA",
"INSTRUCTION_TYPE_XCHG",
"INSTRUCTION_TYPE_CMP",
"INSTRUCTION_TYPE_TEST",
"INSTRUCTION_TYPE_PUSH",
"INSTRUCTION_TYPE_AND",
"INSTRUCTION_TYPE_OR",
"INSTRUCTION_TYPE_POP",
"INSTRUCTION_TYPE_JMP",
"INSTRUCTION_TYPE_JMPC",
"INSTRUCTION_TYPE_JECXZ",
"INSTRUCTION_TYPE_SETC",
"INSTRUCTION_TYPE_MOVC",
"INSTRUCTION_TYPE_LOOP",
"INSTRUCTION_TYPE_CALL",
"INSTRUCTION_TYPE_RET",
"INSTRUCTION_TYPE_ENTER",
"INSTRUCTION_TYPE_INT",
"INSTRUCTION_TYPE_BT",
"INSTRUCTION_TYPE_BTS",
"INSTRUCTION_TYPE_BTR",
"INSTRUCTION_TYPE_BTC",
"INSTRUCTION_TYPE_BSF",
"INSTRUCTION_TYPE_BSR",
"INSTRUCTION_TYPE_BSWAP",
"INSTRUCTION_TYPE_SGDT",
"INSTRUCTION_TYPE_SIDT",
"INSTRUCTION_TYPE_SLDT",
"INSTRUCTION_TYPE_LFP",
"INSTRUCTION_TYPE_CLD",
"INSTRUCTION_TYPE_STD",
"INSTRUCTION_TYPE_XLAT",
"INSTRUCTION_TYPE_FCMOVC",
"INSTRUCTION_TYPE_FADD",
"INSTRUCTION_TYPE_FADDP",
"INSTRUCTION_TYPE_FIADD",
"INSTRUCTION_TYPE_FSUB",
"INSTRUCTION_TYPE_FSUBP",
"INSTRUCTION_TYPE_FISUB",
"INSTRUCTION_TYPE_FSUBR",
"INSTRUCTION_TYPE_FSUBRP",
"INSTRUCTION_TYPE_FISUBR",
"INSTRUCTION_TYPE_FMUL",
"INSTRUCTION_TYPE_FMULP",
"INSTRUCTION_TYPE_FIMUL",
"INSTRUCTION_TYPE_FDIV",
"INSTRUCTION_TYPE_FDIVP",
"INSTRUCTION_TYPE_FDIVR",
"INSTRUCTION_TYPE_FDIVRP",
"INSTRUCTION_TYPE_FIDIV",
"INSTRUCTION_TYPE_FIDIVR",
"INSTRUCTION_TYPE_FCOM",
"INSTRUCTION_TYPE_FCOMP",
"INSTRUCTION_TYPE_FCOMPP",
"INSTRUCTION_TYPE_FCOMI",
"INSTRUCTION_TYPE_FCOMIP",
"INSTRUCTION_TYPE_FUCOM",
"INSTRUCTION_TYPE_FUCOMP",
"INSTRUCTION_TYPE_FUCOMPP",
"INSTRUCTION_TYPE_FUCOMI",
"INSTRUCTION_TYPE_FUCOMIP",
"INSTRUCTION_TYPE_FST",
"INSTRUCTION_TYPE_FSTP",
"INSTRUCTION_TYPE_FIST",
"INSTRUCTION_TYPE_FISTP",
"INSTRUCTION_TYPE_FISTTP",
"INSTRUCTION_TYPE_FLD",
"INSTRUCTION_TYPE_FILD",
"INSTRUCTION_TYPE_FICOM",
"INSTRUCTION_TYPE_FICOMP",
"INSTRUCTION_TYPE_FFREE",
"INSTRUCTION_TYPE_FFREEP",
"INSTRUCTION_TYPE_FXCH",
"INSTRUCTION_TYPE_SYSENTER",
"INSTRUCTION_TYPE_FPU_CTRL",
"INSTRUCTION_TYPE_FPU",
"INSTRUCTION_TYPE_MMX",
"INSTRUCTION_TYPE_SSE",
"INSTRUCTION_TYPE_OTHER",
"INSTRUCTION_TYPE_PRIV",
NULL
};
/*
* Operand types borrowed from "libdasm.h"
*/
char *operand_types[] = {
"OPERAND_TYPE_NONE",
"OPERAND_TYPE_MEMORY",
"OPERAND_TYPE_REGISTER",
"OPERAND_TYPE_IMMEDIATE",
NULL
};
/*
* Registers borrowed from "libdasm.h"
*/
char *registers[] = {
"REGISTER_EAX",
"REGISTER_ECX",
"REGISTER_EDX",
"REGISTER_EBX",
"REGISTER_ESP",
"REGISTER_EBP",
"REGISTER_ESI",
"REGISTER_EDI",
"REGISTER_NOP",
NULL
};
/*
* Register types borrowed from "libdasm.h"
*/
char *register_types[] = {
"REGISTER_TYPE_GEN",
"REGISTER_TYPE_SEGMENT",
"REGISTER_TYPE_DEBUG",
"REGISTER_TYPE_CONTROL",
"REGISTER_TYPE_TEST",
"REGISTER_TYPE_XMM",
"REGISTER_TYPE_MMX",
"REGISTER_TYPE_FPU",
NULL
};
/*
* Define INST class
*/
typedef struct {
PyObject_HEAD
unsigned long type; // Instruction type and flags
const char *mnemonic; // Instruction mnemonic
int flags1; // First operand flags (if any)
int flags2; // Second operand flags (if any)
int flags3; // Additional operand flags (if any)
int modrm; // Is MODRM byte present?
short eflags_affected; // Processor eflags affected
short eflags_used; // Processor eflags used by this instruction
int iop_written; // mask of affected implied registers (written)
int iop_read; // mask of affected implied registers (read)
} INSTObject;
static void INSTObject_dealloc(INSTObject *self)
{
Py_TYPE(self)->tp_free((PyObject *)self);
}
static int INSTObject_init(INSTObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {
"type", "mnemonic", "flags1", "flags2", "flags3", "modrm",
"eflags_affected", "eflags_used", "iop_written", "iop_read",
NULL
};
const char *format = "|ksiiiihhii";
int success = PyArg_ParseTupleAndKeywords(
args, kwds, format, kwlist,
&self->type, &self->mnemonic, &self->flags1, &self->flags2,
&self->flags3, &self->modrm, &self->eflags_affected,
&self->eflags_used, &self->iop_written, &self->iop_read
);
if (!success) {
return -1;
}
return 0;
}
static PyMemberDef INSTObject_members[] = {
{"type", T_ULONG, offsetof(INSTObject, type), 0, "Instruction type"},
{"mnemonic", T_STRING, offsetof(INSTObject, mnemonic), 0, "Instruction mnemonic"},
{"flags1", T_INT, offsetof(INSTObject, flags1), 0, "First operand flags"},
{"flags2", T_INT, offsetof(INSTObject, flags2), 0, "Second operand flags"},
{"flags3", T_INT, offsetof(INSTObject, flags3), 0, "Additional operand flags"},
{"modrm", T_INT, offsetof(INSTObject, modrm), 0, "Is MODRM byte present?"},
{"eflags_affected", T_SHORT, offsetof(INSTObject, eflags_affected), 0,
"Processor eflags affected"},
{"eflags_used", T_SHORT, offsetof(INSTObject, eflags_used), 0,
"Processor eflags used by this instruction"},
{"iop_written", T_INT, offsetof(INSTObject, iop_written), 0,
"mask of affected implied registers"},
{"iop_read", T_INT, offsetof(INSTObject, iop_read), 0,
"mask of affected implied registers"},
{NULL} /* Sentinel */
};
// TODO: Use C99 Structure initialization
static PyTypeObject INSTType = {
PyVarObject_HEAD_INIT(NULL, 0)
"pydasm.INST", /* tp_name */
sizeof(INSTObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)INSTObject_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"INST objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
INSTObject_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)INSTObject_init, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
/*
* Define Operand for the instruction
*/
typedef struct {
PyObject_HEAD
int type; // Operand type (register, memory, etc)
int reg; // Register (if any)
int basereg; // Base register (if any)
int indexreg; // Index register (if any)
int scale; // Scale (if any)
int dispbytes; // Displacement bytes (0 = no displacement)
int dispoffset; // Displacement value offset
int immbytes; // Immediate bytes (0 = no immediate)
int immoffset; // Immediate value offset
int sectionbytes; // Section prefix bytes (0 = no section prefix)
unsigned int section; // Section prefix value
unsigned long displacement; // Displacement value
unsigned long immediate; // Immediate value
int flags; // Operand flags
} OPERANDObject;
static void OPERANDObject_dealloc(OPERANDObject *self)
{
Py_TYPE(self)->tp_free((PyObject *)self);
}
static int
OPERANDObject_init(OPERANDObject *self, PyObject *args, PyObject *kwds)
{
static char *kwlist[] = {
"type", "reg", "basereg", "indexreg", "scale",
"dispbytes", "dispoffset", "immbytes", "immoffset",
"sectionbytes", "section", "displacement", "immediate", "flags",
NULL
};
const char *format = "|iiiiiiiiiiIkki";
int success = PyArg_ParseTupleAndKeywords(
args, kwds, format, kwlist,
&self->type, &self->reg, &self->basereg, &self->indexreg,
&self->scale, &self->dispbytes, &self->dispoffset,
&self->immbytes, &self->immoffset, &self->sectionbytes,
&self->section, &self->displacement, &self->immediate,
&self->flags
);
if (!success) {
return -1;
}
return 0;
}
static PyMemberDef OPERANDObject_members[] = {
{"type", T_INT, offsetof(OPERANDObject, type), 0,
"Operand type (register, memory, etc)"},
{"reg", T_INT, offsetof(OPERANDObject, reg), 0, "Register"},
{"basereg", T_INT, offsetof(OPERANDObject, basereg), 0, "Base register"},
{"indexreg", T_INT, offsetof(OPERANDObject, indexreg), 0, "Index register"},
{"scale", T_INT, offsetof(OPERANDObject, scale), 0, "Scale"},
{"dispbytes", T_INT, offsetof(OPERANDObject, dispbytes), 0,
"Displacement bytes (0 = no displacement)"},
{"dispoffset", T_INT, offsetof(OPERANDObject, dispoffset), 0,
"Displacement value offset"},
{"immbytes", T_INT, offsetof(OPERANDObject, immbytes), 0,
"Immediate bytes (0 = no immediate)"},
{"immoffset", T_INT, offsetof(OPERANDObject, immoffset), 0,
"Immediate value offset"},
{"sectionbytes", T_INT, offsetof(OPERANDObject, sectionbytes), 0,
"Section prefix bytes (0 = no section prefix)"},
{"section", T_UINT, offsetof(OPERANDObject, section), 0,
"Section prefix value"},
{"displacement", T_ULONG, offsetof(OPERANDObject, displacement), 0,
"Displacement value"},
{"immediate", T_ULONG, offsetof(OPERANDObject, immediate), 0,
"Immediate value"},
{"flags", T_INT, offsetof(OPERANDObject, flags), 0, "Operand flags"},
{NULL} /* Sentinel */
};
// TODO: Use C99 Structure initialization
static PyTypeObject OPERANDType = {
PyVarObject_HEAD_INIT(NULL, 0)
"pydasm.OPERAND", /* tp_name */
sizeof(OPERANDObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)OPERANDObject_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"OPERAND objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
OPERANDObject_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)OPERANDObject_init, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
/*
* Define INSTRUCTION class
*/
typedef struct {
PyObject_HEAD
int length; // Instruction length
int type; // Instruction type
int mode; // Addressing mode
unsigned int opcode; // Actual opcode
unsigned int modrm; // MODRM byte
unsigned int sib; // SIB byte
int modrm_offset; // MODRM byte offset
int extindex; // Extension table index
int fpuindex; // FPU table index
int dispbytes; // Displacement bytes (0 = no displacement)
int immbytes; // Immediate bytes (0 = no immediate)
int sectionbytes; // Section prefix bytes (0 = no section prefix)
PyObject *op1; // First operand (if any)
PyObject *op2; // Second operand (if any)
PyObject *op3; // Additional operand (if any)
PyObject *ptr; // Pointer to instruction table
int flags; // Instruction flags
short eflags_affected; // Process eflags affected
short eflags_used; // Processor eflags used by this instruction
int iop_written; // mask of affected implied registers (written)
int iop_read; // mask of affected implied registers (read)
} INSTRUCTIONObject;
static void INSTRUCTIONObject_dealloc(INSTRUCTIONObject *self)
{
Py_XDECREF(self->op1);
Py_XDECREF(self->op2);
Py_XDECREF(self->op3);
Py_XDECREF(self->ptr);
Py_TYPE(self)->tp_free((PyObject *)self);
}
static int
INSTRUCTIONObject_init(INSTRUCTIONObject *self, PyObject *args, PyObject *kwds)
{
PyObject *op1 = NULL;
PyObject *op2 = NULL;
PyObject *op3 = NULL;
PyObject *ptr = NULL;
PyObject *tmp = NULL;
static char *kwlist[] = {
"length", "type", "mode", "opcode", "modrm", "sib", "modrm_offset",
"extindex", "fpuindex", "dispbytes", "immbytes", "sectionbytes",
"op1", "op2", "op3", "ptr", "flags", "eflags_affected",
"eflags_used", "iop_written", "iop_read"
};
static char *format = "iiiIIIiiiiiiOOOOihhii";
int success = PyArg_ParseTupleAndKeywords(
args, kwds, format, kwlist,
&self->length, &self->type, &self->mode, &self->opcode,
&self->modrm, &self->sib, &self->modrm_offset, &self->extindex,
&self->fpuindex, &self->dispbytes, &self->immbytes,
&self->sectionbytes, &op1, &op2, &op3, &ptr, &self->flags,
&self->eflags_affected, &self->eflags_used,
&self->iop_written, &self->iop_read
);
if (!success) {
return -1;
}
if (op1) {
tmp = self->op1;
Py_INCREF(op1);
self->op1 = op1;
Py_XDECREF(tmp);
}
if (op2) {
tmp = self->op2;
Py_INCREF(op2);
self->op2 = op2;
Py_XDECREF(tmp);
}
if (op3) {
tmp = self->op3;
Py_INCREF(op3);
self->op3 = op3;
Py_XDECREF(tmp);
}
if (ptr) {
tmp = self->ptr;
Py_INCREF(ptr);
self->ptr = ptr;
Py_XDECREF(tmp);
}
return 0;
}
static PyMemberDef INSTRUCTIONObject_memebers[] = {
{"length", T_INT, offsetof(INSTRUCTIONObject, length), 0, "Instruction length"},
{"type", T_INT, offsetof(INSTRUCTIONObject, type), 0, "Instruction type"},
{"mode", T_INT, offsetof(INSTRUCTIONObject, mode), 0, "Addressing mode"},
{"opcode", T_UINT, offsetof(INSTRUCTIONObject, opcode), 0, "Actual opcode"},
{"modrm", T_UINT, offsetof(INSTRUCTIONObject, modrm), 0, "MODRM byte"},
{"sib", T_UINT, offsetof(INSTRUCTIONObject, sib), 0, "SIB byte"},
{"modrm_offset", T_INT, offsetof(INSTRUCTIONObject, modrm_offset), 0, "MODRM byte offset"},
{"extindex", T_INT, offsetof(INSTRUCTIONObject, extindex), 0, "Extension table index"},
{"fpuindex", T_INT, offsetof(INSTRUCTIONObject, fpuindex), 0, "FPU table index"},
{"dispbytes", T_INT, offsetof(INSTRUCTIONObject, dispbytes), 0,
"Displacement bytes (0 = no displacement)"},
{"immbytes", T_INT, offsetof(INSTRUCTIONObject, immbytes), 0,
"Immediate bytes (0 = no immediate)"},
{"sectionbytes", T_INT, offsetof(INSTRUCTIONObject, sectionbytes), 0,
"Section prefix bytes (0 = no section prefix)"},
{"op1", T_OBJECT, offsetof(INSTRUCTIONObject, op1), 0, "First operand"},
{"op2", T_OBJECT, offsetof(INSTRUCTIONObject, op2), 0, "Second operand"},
{"op3", T_OBJECT, offsetof(INSTRUCTIONObject, op3), 0, "Additional operand"},
{"ptr", T_OBJECT, offsetof(INSTRUCTIONObject, ptr), 0, "Instruction table"},
{"flags", T_INT, offsetof(INSTRUCTIONObject, flags), 0, "Instruction flags"},
{"eflags_affected", T_SHORT, offsetof(INSTRUCTIONObject, eflags_affected), 0,
"Process eflags effected"},
{"eflags_used", T_SHORT, offsetof(INSTRUCTIONObject, eflags_used), 0,
"Process eflags used by this instruction"},
{"iop_written", T_INT, offsetof(INSTRUCTIONObject, iop_written), 0,
"mask of affected implied registers (written)"},
{"iop_read", T_INT, offsetof(INSTRUCTIONObject, iop_read), 0,
"mask of affected implied registers (read)"},
{NULL} /* Sentinel */
};
// TODO: Use C99 Structure initialization
static PyTypeObject INSTRUCTIONType = {
PyVarObject_HEAD_INIT(NULL, 0)
"pydasm.INSTRUCTION", /* tp_name */
sizeof(INSTRUCTIONObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)INSTRUCTIONObject_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
"INSTRUCTION objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
INSTRUCTIONObject_memebers, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)INSTRUCTIONObject_init, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
/*
* For module init
*/
static PyModuleDef pydasm_module = {
PyModuleDef_HEAD_INIT,
"pydasm",
"Python module wrapping libdasm",
-1,
NULL, NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC PyInit_pydasm(void)
{
int i;
PyObject *m;
if (PyType_Ready(&INSTType) < 0) {
return NULL;
}
if (PyType_Ready(&OPERANDType) < 0) {
return NULL;
}
if (PyType_Ready(&INSTRUCTIONType) < 0) {
return NULL;
}
m = PyModule_Create(&pydasm_module);
if (m == NULL) {
return NULL;
}
Py_INCREF(&INSTType);
PyModule_AddObject(m, "INST", (PyObject *)&INSTType);
Py_INCREF(&OPERANDType);
PyModule_AddObject(m, "OPERAND", (PyObject *)&OPERANDType);
Py_INCREF(&INSTRUCTIONType);
PyModule_AddObject(m, "INSTRUCTION", (PyObject *)&INSTRUCTIONType);
PyModule_AddIntMacro(m, FORMAT_ATT);
PyModule_AddIntMacro(m, FORMAT_INTEL);
PyModule_AddIntMacro(m, MODE_16);
PyModule_AddIntMacro(m, MODE_32);
/*
* TODO: test code
* class LAVA(object):
* pass
*
*/
PyObject *pClassName = PyUnicode_FromString("VALA");
PyObject *pClassBase = PyTuple_New(1);
PyTuple_SetItem(pClassBase, 0, (PyObject *)&PyBaseObject_Type);
PyObject *pClassDict = PyDict_New();
PyObject *args = PyTuple_New(3);
PyTuple_SetItem(args, 0, pClassName);
PyTuple_SetItem(args, 1, pClassBase);
PyTuple_SetItem(args, 2, pClassDict);
PyObject *lava = PyObject_CallObject((PyObject *)&PyType_Type, args);
PyModule_AddObject(m, "lava", lava);
Py_DECREF(pClassName);
Py_DECREF(pClassBase);
Py_DECREF(pClassDict);
Py_DECREF(args);
// end test
for (i = 0; instruction_types[i]; ++i) {
PyModule_AddIntConstant(m, instruction_types[i], i);
}
for (i = 0; operand_types[i]; ++i) {
PyModule_AddIntConstant(m, operand_types[i], i);
}
for (i = 0; registers[i]; ++i) {
PyModule_AddIntConstant(m, registers[i], i);
}
for (i = 0; register_types[i]; ++i) {
PyModule_AddIntConstant(m, register_types[i], i);
}
return m;
}
int main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(EXIT_FAILURE);
}
Py_SetProgramName(program);
Py_Initialize();
PyInit_pydasm();
PyMem_RawFree(program);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment