-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory.js
150 lines (146 loc) · 4.26 KB
/
memory.js
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
function WebCPU_Memory(){
this.initMemory();
}
WebCPU_Memory.prototype = {
addMemoryPage: function(memoryPage){
this.root.push(memoryPage);
},
initMemory: function(){
this.root = new Array();
this.addMemoryPage(new WebCPU_MemoryPage());
},
getMemoryPageCountFromMemoryPageInstance: function(memoryPage){
for(var i = 0; i < this.root.length; i++){
if(this.root[i] == memoryPage){
return i;
}
}
return undefined;
},
getMemoryPageInstanceFromLabelNumber: function(labelnum){
//ラベルをメモリから探し出す
for(var i = 0; i < this.root.length; i++){
if(this.root[i].data[0] instanceof WebCPU_Instruction_LB){
if(this.root[i].data[0].imm32 == labelnum){
return this.root[i];
}
}
}
return undefined;
},
allocateMemoryPage: function(type, length){
//指定された型と長さのメモリを確保して返す。
length = length ? length : 0;
var m = new WebCPU_MemoryPage();
m.addMemoryData(new WebCPU_Instruction_LB());
m.addMemoryData(new WebCPU_Instruction_DATA());
m.data[1].type = type;
m.data[1].data = new Array(length);
return m;
},
}
function WebCPU_MemoryPage(size){
size = size ? size : 0;
this.data = new Array(size);
}
WebCPU_MemoryPage.prototype = {
addMemoryData: function(memoryData){
this.data.push(memoryData);
},
}
function WebCPU_Pointer(memoryPage){
this.memoryPage = memoryPage;
this.memoryType = 0;
this.addressOffset = 0;
this.labelNumber = null;
//ポインタタイプ判別
if(this.memoryPage && this.memoryPage.data && this.memoryPage.data.length > 0){
if(this.memoryPage.data[0] instanceof WebCPU_Instruction_LB){
//ラベルが直下にあればそのラベル番号をポインタに記憶する
this.labelNumber = this.memoryPage.data[0].imm32;
this.memoryType = WebCPU.pType.VPtr;
if(this.memoryPage.data[1]){
if(this.memoryPage.data[1] instanceof WebCPU_Instruction_DATA){
//ラベル直下がDATAだった場合はそのDATAの型に従う
var type = this.memoryPage.data[1].type;
if(1 <= type && type < this.memoryTypeStrList.length){
this.memoryType = type;
} else{
console.log("unknown data type.");
}
}
}
}
}
this.memoryTypeStr = this.memoryTypeStrList[this.memoryType];
}
WebCPU_Pointer.prototype = {
memoryTypeStrList: [
"Undefined",
"VPtr", // コードポインタ?
"SINT8", // 8bitの符号付き, いわゆる signed char.
"UINT8",
"SINT16", // 16bitの符号付き, いわゆる short.
"UINT16",
"SINT32",
"UINT32",
"SINT4",
"UINT4",
"SINT2",
"UINT2",
"SINT1", // 代入できるのは0か-1のみ.
"UINT1",
"SINT12",
"UINT12",
"SINT20",
"UINT20",
"SINT24",
"UINT24",
"SINT28",
"UINT28", //0x15
],
toString: function(){
if(this.memoryType == 0xC0FFEE){
//API Address, NOT OFFICIAL
return "#API";
}
if(this.labelNumber == null){
if(this.memoryPage && this.memoryPage.data && this.memoryPage.data[1].data){
return this.memoryTypeStrList[this.memoryType] + ":" + this.addressOffset + " / " + this.memoryPage.data[1].data.length;
}
return this.memoryTypeStrList[this.memoryType] + ":" + this.addressOffset;
}
return "Label#0x" + this.labelNumber.toString(16).toUpperCase() + ":" + this.addressOffset + ":" + this.memoryTypeStr;
},
readData: function(env){
if(this.memoryPage.data[1].data.length <= this.addressOffset){
throw new WebCPU_Exception(2, ["Attempt to access to out of pointer range."]);
}
var data = this.memoryPage.data[1].data[this.addressOffset];
if(data === undefined){
throw new WebCPU_Exception(2, ["Attempt to access to undefined value."]);
}
return data;
},
writeData: function(env, data){
if(this.memoryPage.data[1].data.length <= this.addressOffset){
throw new WebCPU_Exception(2, ["Attempt to access to out of pointer range."]);
}
this.memoryPage.data[1].data[this.addressOffset] = data;
},
getCopy: function(){
var copy = new WebCPU_Pointer();
copy.memoryPage = this.memoryPage;
copy.memoryType = this.memoryType;
copy.memoryTypeStr = this.memoryTypeStr;
copy.addressOffset = this.addressOffset;
copy.labelNumber = this.labelNumber;
return copy;
},
verifySameMemoryPageAs: function(p){
if(p && p.memoryPage && this.memoryPage && this.memoryPage == p.memoryPage){
return true;
}
return false;
}
}