Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F100195154
index.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Jan 28, 23:02
Size
5 KB
Mime Type
text/x-java
Expires
Thu, Jan 30, 23:02 (16 h, 48 m)
Engine
blob
Format
Raw Data
Handle
23878757
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
index.js
View Options
// TODO(sven): add flow in here
import { isSignature, isNumberLiteral } from "@webassemblyjs/ast";
import { assert } from "mamacro";
export function moduleContextFromModuleAST(m) {
const moduleContext = new ModuleContext();
assert(m.type === "Module");
m.fields.forEach(field => {
switch (field.type) {
case "Start": {
moduleContext.setStart(field.index);
break;
}
case "TypeInstruction": {
moduleContext.addType(field);
break;
}
case "Func": {
moduleContext.addFunction(field);
break;
}
case "Global": {
moduleContext.defineGlobal(field);
break;
}
case "ModuleImport": {
switch (field.descr.type) {
case "GlobalType": {
moduleContext.importGlobal(
field.descr.valtype,
field.descr.mutability
);
break;
}
case "Memory": {
moduleContext.addMemory(
field.descr.limits.min,
field.descr.limits.max
);
break;
}
case "FuncImportDescr": {
moduleContext.importFunction(field.descr);
break;
}
case "Table": {
// FIXME(sven): not implemented yet
break;
}
default:
throw new Error(
"Unsupported ModuleImport of type " +
JSON.stringify(field.descr.type)
);
}
break;
}
case "Memory": {
moduleContext.addMemory(field.limits.min, field.limits.max);
break;
}
}
});
return moduleContext;
}
/**
* Module context for type checking
*/
export class ModuleContext {
constructor() {
this.funcs = [];
this.funcsOffsetByIdentifier = [];
this.types = [];
this.globals = [];
this.globalsOffsetByIdentifier = [];
this.mems = [];
// Current stack frame
this.locals = [];
this.labels = [];
this.return = [];
this.debugName = "unknown";
this.start = null;
}
/**
* Set start segment
*/
setStart(index) {
this.start = index.value;
}
/**
* Get start function
*/
getStart() {
return this.start;
}
/**
* Reset the active stack frame
*/
newContext(debugName, expectedResult) {
this.locals = [];
this.labels = [expectedResult];
this.return = expectedResult;
this.debugName = debugName;
}
/**
* Functions
*/
addFunction(func /*: Func*/) {
// eslint-disable-next-line prefer-const
let { params: args = [], results: result = [] } = func.signature || {};
args = args.map(arg => arg.valtype);
this.funcs.push({ args, result });
if (typeof func.name !== "undefined") {
this.funcsOffsetByIdentifier[func.name.value] = this.funcs.length - 1;
}
}
importFunction(funcimport) {
if (isSignature(funcimport.signature)) {
// eslint-disable-next-line prefer-const
let { params: args, results: result } = funcimport.signature;
args = args.map(arg => arg.valtype);
this.funcs.push({ args, result });
} else {
assert(isNumberLiteral(funcimport.signature));
const typeId = funcimport.signature.value;
assert(this.hasType(typeId));
const signature = this.getType(typeId);
this.funcs.push({
args: signature.params.map(arg => arg.valtype),
result: signature.results
});
}
if (typeof funcimport.id !== "undefined") {
// imports are first, we can assume their index in the array
this.funcsOffsetByIdentifier[funcimport.id.value] = this.funcs.length - 1;
}
}
hasFunction(index) {
return typeof this.getFunction(index) !== "undefined";
}
getFunction(index) {
if (typeof index !== "number") {
throw new Error("getFunction only supported for number index");
}
return this.funcs[index];
}
getFunctionOffsetByIdentifier(name) {
assert(typeof name === "string");
return this.funcsOffsetByIdentifier[name];
}
/**
* Labels
*/
addLabel(result) {
this.labels.unshift(result);
}
hasLabel(index) {
return this.labels.length > index && index >= 0;
}
getLabel(index) {
return this.labels[index];
}
popLabel() {
this.labels.shift();
}
/**
* Locals
*/
hasLocal(index) {
return typeof this.getLocal(index) !== "undefined";
}
getLocal(index) {
return this.locals[index];
}
addLocal(type) {
this.locals.push(type);
}
/**
* Types
*/
addType(type) {
assert(type.functype.type === "Signature");
this.types.push(type.functype);
}
hasType(index) {
return this.types[index] !== undefined;
}
getType(index) {
return this.types[index];
}
/**
* Globals
*/
hasGlobal(index) {
return this.globals.length > index && index >= 0;
}
getGlobal(index) {
return this.globals[index].type;
}
getGlobalOffsetByIdentifier(name) {
assert(typeof name === "string");
return this.globalsOffsetByIdentifier[name];
}
defineGlobal(global /*: Global*/) {
const type = global.globalType.valtype;
const mutability = global.globalType.mutability;
this.globals.push({ type, mutability });
if (typeof global.name !== "undefined") {
this.globalsOffsetByIdentifier[global.name.value] =
this.globals.length - 1;
}
}
importGlobal(type, mutability) {
this.globals.push({ type, mutability });
}
isMutableGlobal(index) {
return this.globals[index].mutability === "var";
}
isImmutableGlobal(index) {
return this.globals[index].mutability === "const";
}
/**
* Memories
*/
hasMemory(index) {
return this.mems.length > index && index >= 0;
}
addMemory(min, max) {
this.mems.push({ min, max });
}
getMemory(index) {
return this.mems[index];
}
}
Event Timeline
Log In to Comment