Projekt

Obecné

Profil

Stáhnout (9.35 KB) Statistiky
| Větev: | Revize:
1
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2

    
3
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
4

    
5
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
6

    
7
// TODO(sven): add flow in here
8
import { isSignature, isNumberLiteral } from "@webassemblyjs/ast";
9
export function moduleContextFromModuleAST(m) {
10
  var moduleContext = new ModuleContext();
11

    
12
  if (!(m.type === "Module")) {
13
    throw new Error('m.type === "Module"' + " error: " + (undefined || "unknown"));
14
  }
15

    
16
  m.fields.forEach(function (field) {
17
    switch (field.type) {
18
      case "Start":
19
        {
20
          moduleContext.setStart(field.index);
21
          break;
22
        }
23

    
24
      case "TypeInstruction":
25
        {
26
          moduleContext.addType(field);
27
          break;
28
        }
29

    
30
      case "Func":
31
        {
32
          moduleContext.addFunction(field);
33
          break;
34
        }
35

    
36
      case "Global":
37
        {
38
          moduleContext.defineGlobal(field);
39
          break;
40
        }
41

    
42
      case "ModuleImport":
43
        {
44
          switch (field.descr.type) {
45
            case "GlobalType":
46
              {
47
                moduleContext.importGlobal(field.descr.valtype, field.descr.mutability);
48
                break;
49
              }
50

    
51
            case "Memory":
52
              {
53
                moduleContext.addMemory(field.descr.limits.min, field.descr.limits.max);
54
                break;
55
              }
56

    
57
            case "FuncImportDescr":
58
              {
59
                moduleContext.importFunction(field.descr);
60
                break;
61
              }
62

    
63
            case "Table":
64
              {
65
                // FIXME(sven): not implemented yet
66
                break;
67
              }
68

    
69
            default:
70
              throw new Error("Unsupported ModuleImport of type " + JSON.stringify(field.descr.type));
71
          }
72

    
73
          break;
74
        }
75

    
76
      case "Memory":
77
        {
78
          moduleContext.addMemory(field.limits.min, field.limits.max);
79
          break;
80
        }
81
    }
82
  });
83
  return moduleContext;
84
}
85
/**
86
 * Module context for type checking
87
 */
88

    
89
export var ModuleContext =
90
/*#__PURE__*/
91
function () {
92
  function ModuleContext() {
93
    _classCallCheck(this, ModuleContext);
94

    
95
    this.funcs = [];
96
    this.funcsOffsetByIdentifier = [];
97
    this.types = [];
98
    this.globals = [];
99
    this.globalsOffsetByIdentifier = [];
100
    this.mems = []; // Current stack frame
101

    
102
    this.locals = [];
103
    this.labels = [];
104
    this.return = [];
105
    this.debugName = "unknown";
106
    this.start = null;
107
  }
108
  /**
109
   * Set start segment
110
   */
111

    
112

    
113
  _createClass(ModuleContext, [{
114
    key: "setStart",
115
    value: function setStart(index) {
116
      this.start = index.value;
117
    }
118
    /**
119
     * Get start function
120
     */
121

    
122
  }, {
123
    key: "getStart",
124
    value: function getStart() {
125
      return this.start;
126
    }
127
    /**
128
     * Reset the active stack frame
129
     */
130

    
131
  }, {
132
    key: "newContext",
133
    value: function newContext(debugName, expectedResult) {
134
      this.locals = [];
135
      this.labels = [expectedResult];
136
      this.return = expectedResult;
137
      this.debugName = debugName;
138
    }
139
    /**
140
     * Functions
141
     */
142

    
143
  }, {
144
    key: "addFunction",
145
    value: function addFunction(func
146
    /*: Func*/
147
    ) {
148
      // eslint-disable-next-line prefer-const
149
      var _ref = func.signature || {},
150
          _ref$params = _ref.params,
151
          args = _ref$params === void 0 ? [] : _ref$params,
152
          _ref$results = _ref.results,
153
          result = _ref$results === void 0 ? [] : _ref$results;
154

    
155
      args = args.map(function (arg) {
156
        return arg.valtype;
157
      });
158
      this.funcs.push({
159
        args: args,
160
        result: result
161
      });
162

    
163
      if (typeof func.name !== "undefined") {
164
        this.funcsOffsetByIdentifier[func.name.value] = this.funcs.length - 1;
165
      }
166
    }
167
  }, {
168
    key: "importFunction",
169
    value: function importFunction(funcimport) {
170
      if (isSignature(funcimport.signature)) {
171
        // eslint-disable-next-line prefer-const
172
        var _funcimport$signature = funcimport.signature,
173
            args = _funcimport$signature.params,
174
            result = _funcimport$signature.results;
175
        args = args.map(function (arg) {
176
          return arg.valtype;
177
        });
178
        this.funcs.push({
179
          args: args,
180
          result: result
181
        });
182
      } else {
183
        if (!isNumberLiteral(funcimport.signature)) {
184
          throw new Error('isNumberLiteral(funcimport.signature)' + " error: " + (undefined || "unknown"));
185
        }
186

    
187
        var typeId = funcimport.signature.value;
188

    
189
        if (!this.hasType(typeId)) {
190
          throw new Error('this.hasType(typeId)' + " error: " + (undefined || "unknown"));
191
        }
192

    
193
        var signature = this.getType(typeId);
194
        this.funcs.push({
195
          args: signature.params.map(function (arg) {
196
            return arg.valtype;
197
          }),
198
          result: signature.results
199
        });
200
      }
201

    
202
      if (typeof funcimport.id !== "undefined") {
203
        // imports are first, we can assume their index in the array
204
        this.funcsOffsetByIdentifier[funcimport.id.value] = this.funcs.length - 1;
205
      }
206
    }
207
  }, {
208
    key: "hasFunction",
209
    value: function hasFunction(index) {
210
      return typeof this.getFunction(index) !== "undefined";
211
    }
212
  }, {
213
    key: "getFunction",
214
    value: function getFunction(index) {
215
      if (typeof index !== "number") {
216
        throw new Error("getFunction only supported for number index");
217
      }
218

    
219
      return this.funcs[index];
220
    }
221
  }, {
222
    key: "getFunctionOffsetByIdentifier",
223
    value: function getFunctionOffsetByIdentifier(name) {
224
      if (!(typeof name === "string")) {
225
        throw new Error('typeof name === "string"' + " error: " + (undefined || "unknown"));
226
      }
227

    
228
      return this.funcsOffsetByIdentifier[name];
229
    }
230
    /**
231
     * Labels
232
     */
233

    
234
  }, {
235
    key: "addLabel",
236
    value: function addLabel(result) {
237
      this.labels.unshift(result);
238
    }
239
  }, {
240
    key: "hasLabel",
241
    value: function hasLabel(index) {
242
      return this.labels.length > index && index >= 0;
243
    }
244
  }, {
245
    key: "getLabel",
246
    value: function getLabel(index) {
247
      return this.labels[index];
248
    }
249
  }, {
250
    key: "popLabel",
251
    value: function popLabel() {
252
      this.labels.shift();
253
    }
254
    /**
255
     * Locals
256
     */
257

    
258
  }, {
259
    key: "hasLocal",
260
    value: function hasLocal(index) {
261
      return typeof this.getLocal(index) !== "undefined";
262
    }
263
  }, {
264
    key: "getLocal",
265
    value: function getLocal(index) {
266
      return this.locals[index];
267
    }
268
  }, {
269
    key: "addLocal",
270
    value: function addLocal(type) {
271
      this.locals.push(type);
272
    }
273
    /**
274
     * Types
275
     */
276

    
277
  }, {
278
    key: "addType",
279
    value: function addType(type) {
280
      if (!(type.functype.type === "Signature")) {
281
        throw new Error('type.functype.type === "Signature"' + " error: " + (undefined || "unknown"));
282
      }
283

    
284
      this.types.push(type.functype);
285
    }
286
  }, {
287
    key: "hasType",
288
    value: function hasType(index) {
289
      return this.types[index] !== undefined;
290
    }
291
  }, {
292
    key: "getType",
293
    value: function getType(index) {
294
      return this.types[index];
295
    }
296
    /**
297
     * Globals
298
     */
299

    
300
  }, {
301
    key: "hasGlobal",
302
    value: function hasGlobal(index) {
303
      return this.globals.length > index && index >= 0;
304
    }
305
  }, {
306
    key: "getGlobal",
307
    value: function getGlobal(index) {
308
      return this.globals[index].type;
309
    }
310
  }, {
311
    key: "getGlobalOffsetByIdentifier",
312
    value: function getGlobalOffsetByIdentifier(name) {
313
      if (!(typeof name === "string")) {
314
        throw new Error('typeof name === "string"' + " error: " + (undefined || "unknown"));
315
      }
316

    
317
      return this.globalsOffsetByIdentifier[name];
318
    }
319
  }, {
320
    key: "defineGlobal",
321
    value: function defineGlobal(global
322
    /*: Global*/
323
    ) {
324
      var type = global.globalType.valtype;
325
      var mutability = global.globalType.mutability;
326
      this.globals.push({
327
        type: type,
328
        mutability: mutability
329
      });
330

    
331
      if (typeof global.name !== "undefined") {
332
        this.globalsOffsetByIdentifier[global.name.value] = this.globals.length - 1;
333
      }
334
    }
335
  }, {
336
    key: "importGlobal",
337
    value: function importGlobal(type, mutability) {
338
      this.globals.push({
339
        type: type,
340
        mutability: mutability
341
      });
342
    }
343
  }, {
344
    key: "isMutableGlobal",
345
    value: function isMutableGlobal(index) {
346
      return this.globals[index].mutability === "var";
347
    }
348
  }, {
349
    key: "isImmutableGlobal",
350
    value: function isImmutableGlobal(index) {
351
      return this.globals[index].mutability === "const";
352
    }
353
    /**
354
     * Memories
355
     */
356

    
357
  }, {
358
    key: "hasMemory",
359
    value: function hasMemory(index) {
360
      return this.mems.length > index && index >= 0;
361
    }
362
  }, {
363
    key: "addMemory",
364
    value: function addMemory(min, max) {
365
      this.mems.push({
366
        min: min,
367
        max: max
368
      });
369
    }
370
  }, {
371
    key: "getMemory",
372
    value: function getMemory(index) {
373
      return this.mems[index];
374
    }
375
  }]);
376

    
377
  return ModuleContext;
378
}();
    (1-1/1)