forked from zrax/pycdc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
pyc_object.cpp
103 lines (98 loc) · 2.97 KB
/
pyc_object.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "pyc_object.h"
#include "pyc_module.h"
#include "pyc_numeric.h"
#include "pyc_code.h"
#include "data.h"
#include <cstdio>
PycRef<PycObject> Pyc_None = new PycObject(PycObject::TYPE_NONE);
PycRef<PycObject> Pyc_Ellipsis = new PycObject(PycObject::TYPE_ELLIPSIS);
PycRef<PycObject> Pyc_StopIteration = new PycObject(PycObject::TYPE_STOPITER);
PycRef<PycObject> Pyc_False = new PycObject(PycObject::TYPE_FALSE);
PycRef<PycObject> Pyc_True = new PycObject(PycObject::TYPE_TRUE);
PycRef<PycObject> CreateObject(int type)
{
switch (type) {
case PycObject::TYPE_NULL:
return NULL;
case PycObject::TYPE_NONE:
return Pyc_None;
case PycObject::TYPE_FALSE:
return Pyc_False;
case PycObject::TYPE_TRUE:
return Pyc_True;
case PycObject::TYPE_STOPITER:
return Pyc_StopIteration;
case PycObject::TYPE_ELLIPSIS:
return Pyc_Ellipsis;
case PycObject::TYPE_INT:
return new PycInt(type);
case PycObject::TYPE_INT64:
return new PycLong(type);
case PycObject::TYPE_FLOAT:
return new PycFloat(type);
case PycObject::TYPE_BINARY_FLOAT:
return new PycCFloat(type);
case PycObject::TYPE_COMPLEX:
return new PycComplex(type);
case PycObject::TYPE_BINARY_COMPLEX:
return new PycCComplex(type);
case PycObject::TYPE_LONG:
return new PycLong(type);
case PycObject::TYPE_STRING:
case PycObject::TYPE_INTERNED:
case PycObject::TYPE_STRINGREF:
case PycObject::TYPE_UNICODE:
case PycObject::TYPE_ASCII:
case PycObject::TYPE_ASCII_INTERNED:
case PycObject::TYPE_SHORT_ASCII:
case PycObject::TYPE_SHORT_ASCII_INTERNED:
return new PycString(type);
case PycObject::TYPE_TUPLE:
case PycObject::TYPE_SMALL_TUPLE:
return new PycTuple(type);
case PycObject::TYPE_LIST:
return new PycList(type);
case PycObject::TYPE_DICT:
return new PycDict(type);
case PycObject::TYPE_CODE:
case PycObject::TYPE_CODE2:
return new PycCode(type);
case PycObject::TYPE_SET:
case PycObject::TYPE_FROZENSET:
return new PycSet(type);
default:
fprintf(stderr, "CreateObject: Got unsupported type 0x%X\n", type);
return NULL;
}
}
int CheckRecursionDepth(int currentDepth, int maxDepth)
{
if (currentDepth > maxDepth)
{
fprintf(stderr, "\n# Error: Reached maximum object recursion depth of %i while loading object data\n", maxDepth);
return 0;
}
return 1;
}
PycRef<PycObject> LoadObject(PycData* stream, PycModule* mod, int currentDepth, int maxDepth)
{
PycRef<PycObject> obj;
if (CheckRecursionDepth(currentDepth, maxDepth))
{
int type = stream->getByte();
if (type == PycObject::TYPE_OBREF) {
int index = stream->get32();
obj = mod->getRef(index);
} else {
obj = CreateObject(type & 0x7F);
if (obj != NULL) {
if (type & 0x80)
{
mod->refObject(obj);
}
obj->load(stream, mod, currentDepth + 1, maxDepth);
}
}
}
return obj;
}