Projekt

Obecné

Profil

Stáhnout (9.51 KB) Statistiky
| Větev: | Revize:
1
"use strict";
2

    
3
Object.defineProperty(exports, "__esModule", {
4
  value: true
5
});
6
exports.moduleContextFromModuleAST = moduleContextFromModuleAST;
7
exports.ModuleContext = void 0;
8

    
9
var _ast = require("@webassemblyjs/ast");
10

    
11
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12

    
13
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); } }
14

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

    
17
function moduleContextFromModuleAST(m) {
18
  var moduleContext = new ModuleContext();
19

    
20
  if (!(m.type === "Module")) {
21
    throw new Error('m.type === "Module"' + " error: " + (undefined || "unknown"));
22
  }
23

    
24
  m.fields.forEach(function (field) {
25
    switch (field.type) {
26
      case "Start":
27
        {
28
          moduleContext.setStart(field.index);
29
          break;
30
        }
31

    
32
      case "TypeInstruction":
33
        {
34
          moduleContext.addType(field);
35
          break;
36
        }
37

    
38
      case "Func":
39
        {
40
          moduleContext.addFunction(field);
41
          break;
42
        }
43

    
44
      case "Global":
45
        {
46
          moduleContext.defineGlobal(field);
47
          break;
48
        }
49

    
50
      case "ModuleImport":
51
        {
52
          switch (field.descr.type) {
53
            case "GlobalType":
54
              {
55
                moduleContext.importGlobal(field.descr.valtype, field.descr.mutability);
56
                break;
57
              }
58

    
59
            case "Memory":
60
              {
61
                moduleContext.addMemory(field.descr.limits.min, field.descr.limits.max);
62
                break;
63
              }
64

    
65
            case "FuncImportDescr":
66
              {
67
                moduleContext.importFunction(field.descr);
68
                break;
69
              }
70

    
71
            case "Table":
72
              {
73
                // FIXME(sven): not implemented yet
74
                break;
75
              }
76

    
77
            default:
78
              throw new Error("Unsupported ModuleImport of type " + JSON.stringify(field.descr.type));
79
          }
80

    
81
          break;
82
        }
83

    
84
      case "Memory":
85
        {
86
          moduleContext.addMemory(field.limits.min, field.limits.max);
87
          break;
88
        }
89
    }
90
  });
91
  return moduleContext;
92
}
93
/**
94
 * Module context for type checking
95
 */
96

    
97

    
98
var ModuleContext =
99
/*#__PURE__*/
100
function () {
101
  function ModuleContext() {
102
    _classCallCheck(this, ModuleContext);
103

    
104
    this.funcs = [];
105
    this.funcsOffsetByIdentifier = [];
106
    this.types = [];
107
    this.globals = [];
108
    this.globalsOffsetByIdentifier = [];
109
    this.mems = []; // Current stack frame
110

    
111
    this.locals = [];
112
    this.labels = [];
113
    this.return = [];
114
    this.debugName = "unknown";
115
    this.start = null;
116
  }
117
  /**
118
   * Set start segment
119
   */
120

    
121

    
122
  _createClass(ModuleContext, [{
123
    key: "setStart",
124
    value: function setStart(index) {
125
      this.start = index.value;
126
    }
127
    /**
128
     * Get start function
129
     */
130

    
131
  }, {
132
    key: "getStart",
133
    value: function getStart() {
134
      return this.start;
135
    }
136
    /**
137
     * Reset the active stack frame
138
     */
139

    
140
  }, {
141
    key: "newContext",
142
    value: function newContext(debugName, expectedResult) {
143
      this.locals = [];
144
      this.labels = [expectedResult];
145
      this.return = expectedResult;
146
      this.debugName = debugName;
147
    }
148
    /**
149
     * Functions
150
     */
151

    
152
  }, {
153
    key: "addFunction",
154
    value: function addFunction(func
155
    /*: Func*/
156
    ) {
157
      // eslint-disable-next-line prefer-const
158
      var _ref = func.signature || {},
159
          _ref$params = _ref.params,
160
          args = _ref$params === void 0 ? [] : _ref$params,
161
          _ref$results = _ref.results,
162
          result = _ref$results === void 0 ? [] : _ref$results;
163

    
164
      args = args.map(function (arg) {
165
        return arg.valtype;
166
      });
167
      this.funcs.push({
168
        args: args,
169
        result: result
170
      });
171

    
172
      if (typeof func.name !== "undefined") {
173
        this.funcsOffsetByIdentifier[func.name.value] = this.funcs.length - 1;
174
      }
175
    }
176
  }, {
177
    key: "importFunction",
178
    value: function importFunction(funcimport) {
179
      if ((0, _ast.isSignature)(funcimport.signature)) {
180
        // eslint-disable-next-line prefer-const
181
        var _funcimport$signature = funcimport.signature,
182
            args = _funcimport$signature.params,
183
            result = _funcimport$signature.results;
184
        args = args.map(function (arg) {
185
          return arg.valtype;
186
        });
187
        this.funcs.push({
188
          args: args,
189
          result: result
190
        });
191
      } else {
192
        if (!(0, _ast.isNumberLiteral)(funcimport.signature)) {
193
          throw new Error('isNumberLiteral(funcimport.signature)' + " error: " + (undefined || "unknown"));
194
        }
195

    
196
        var typeId = funcimport.signature.value;
197

    
198
        if (!this.hasType(typeId)) {
199
          throw new Error('this.hasType(typeId)' + " error: " + (undefined || "unknown"));
200
        }
201

    
202
        var signature = this.getType(typeId);
203
        this.funcs.push({
204
          args: signature.params.map(function (arg) {
205
            return arg.valtype;
206
          }),
207
          result: signature.results
208
        });
209
      }
210

    
211
      if (typeof funcimport.id !== "undefined") {
212
        // imports are first, we can assume their index in the array
213
        this.funcsOffsetByIdentifier[funcimport.id.value] = this.funcs.length - 1;
214
      }
215
    }
216
  }, {
217
    key: "hasFunction",
218
    value: function hasFunction(index) {
219
      return typeof this.getFunction(index) !== "undefined";
220
    }
221
  }, {
222
    key: "getFunction",
223
    value: function getFunction(index) {
224
      if (typeof index !== "number") {
225
        throw new Error("getFunction only supported for number index");
226
      }
227

    
228
      return this.funcs[index];
229
    }
230
  }, {
231
    key: "getFunctionOffsetByIdentifier",
232
    value: function getFunctionOffsetByIdentifier(name) {
233
      if (!(typeof name === "string")) {
234
        throw new Error('typeof name === "string"' + " error: " + (undefined || "unknown"));
235
      }
236

    
237
      return this.funcsOffsetByIdentifier[name];
238
    }
239
    /**
240
     * Labels
241
     */
242

    
243
  }, {
244
    key: "addLabel",
245
    value: function addLabel(result) {
246
      this.labels.unshift(result);
247
    }
248
  }, {
249
    key: "hasLabel",
250
    value: function hasLabel(index) {
251
      return this.labels.length > index && index >= 0;
252
    }
253
  }, {
254
    key: "getLabel",
255
    value: function getLabel(index) {
256
      return this.labels[index];
257
    }
258
  }, {
259
    key: "popLabel",
260
    value: function popLabel() {
261
      this.labels.shift();
262
    }
263
    /**
264
     * Locals
265
     */
266

    
267
  }, {
268
    key: "hasLocal",
269
    value: function hasLocal(index) {
270
      return typeof this.getLocal(index) !== "undefined";
271
    }
272
  }, {
273
    key: "getLocal",
274
    value: function getLocal(index) {
275
      return this.locals[index];
276
    }
277
  }, {
278
    key: "addLocal",
279
    value: function addLocal(type) {
280
      this.locals.push(type);
281
    }
282
    /**
283
     * Types
284
     */
285

    
286
  }, {
287
    key: "addType",
288
    value: function addType(type) {
289
      if (!(type.functype.type === "Signature")) {
290
        throw new Error('type.functype.type === "Signature"' + " error: " + (undefined || "unknown"));
291
      }
292

    
293
      this.types.push(type.functype);
294
    }
295
  }, {
296
    key: "hasType",
297
    value: function hasType(index) {
298
      return this.types[index] !== undefined;
299
    }
300
  }, {
301
    key: "getType",
302
    value: function getType(index) {
303
      return this.types[index];
304
    }
305
    /**
306
     * Globals
307
     */
308

    
309
  }, {
310
    key: "hasGlobal",
311
    value: function hasGlobal(index) {
312
      return this.globals.length > index && index >= 0;
313
    }
314
  }, {
315
    key: "getGlobal",
316
    value: function getGlobal(index) {
317
      return this.globals[index].type;
318
    }
319
  }, {
320
    key: "getGlobalOffsetByIdentifier",
321
    value: function getGlobalOffsetByIdentifier(name) {
322
      if (!(typeof name === "string")) {
323
        throw new Error('typeof name === "string"' + " error: " + (undefined || "unknown"));
324
      }
325

    
326
      return this.globalsOffsetByIdentifier[name];
327
    }
328
  }, {
329
    key: "defineGlobal",
330
    value: function defineGlobal(global
331
    /*: Global*/
332
    ) {
333
      var type = global.globalType.valtype;
334
      var mutability = global.globalType.mutability;
335
      this.globals.push({
336
        type: type,
337
        mutability: mutability
338
      });
339

    
340
      if (typeof global.name !== "undefined") {
341
        this.globalsOffsetByIdentifier[global.name.value] = this.globals.length - 1;
342
      }
343
    }
344
  }, {
345
    key: "importGlobal",
346
    value: function importGlobal(type, mutability) {
347
      this.globals.push({
348
        type: type,
349
        mutability: mutability
350
      });
351
    }
352
  }, {
353
    key: "isMutableGlobal",
354
    value: function isMutableGlobal(index) {
355
      return this.globals[index].mutability === "var";
356
    }
357
  }, {
358
    key: "isImmutableGlobal",
359
    value: function isImmutableGlobal(index) {
360
      return this.globals[index].mutability === "const";
361
    }
362
    /**
363
     * Memories
364
     */
365

    
366
  }, {
367
    key: "hasMemory",
368
    value: function hasMemory(index) {
369
      return this.mems.length > index && index >= 0;
370
    }
371
  }, {
372
    key: "addMemory",
373
    value: function addMemory(min, max) {
374
      this.mems.push({
375
        min: min,
376
        max: max
377
      });
378
    }
379
  }, {
380
    key: "getMemory",
381
    value: function getMemory(index) {
382
      return this.mems[index];
383
    }
384
  }]);
385

    
386
  return ModuleContext;
387
}();
388

    
389
exports.ModuleContext = ModuleContext;
    (1-1/1)