| 503 | } |
| 504 | |
| 505 | async run(instance) { |
| 506 | if (!(instance instanceof WebAssembly.Instance)) { |
| 507 | throw new Error("Go.run: WebAssembly.Instance expected"); |
| 508 | } |
| 509 | this._inst = instance; |
| 510 | this.mem = new DataView(this._inst.exports.mem.buffer); |
| 511 | this._values = [ // JS values that Go currently has references to, indexed by reference id |
| 512 | NaN, |
| 513 | 0, |
| 514 | null, |
| 515 | true, |
| 516 | false, |
| 517 | global, |
| 518 | this, |
| 519 | ]; |
| 520 | this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id |
| 521 | this._ids = new Map([ // mapping from JS values to reference ids |
| 522 | [0, 1], |
| 523 | [null, 2], |
| 524 | [true, 3], |
| 525 | [false, 4], |
| 526 | [global, 5], |
| 527 | [this, 6], |
| 528 | ]); |
| 529 | this._idPool = []; // unused ids that have been garbage collected |
| 530 | this.exited = false; // whether the Go program has exited |
| 531 | |
| 532 | // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory. |
| 533 | let offset = 4096; |
| 534 | |
| 535 | const strPtr = (str) => { |
| 536 | const ptr = offset; |
| 537 | const bytes = encoder.encode(str + "\0"); |
| 538 | new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes); |
| 539 | offset += bytes.length; |
| 540 | if (offset % 8 !== 0) { |
| 541 | offset += 8 - (offset % 8); |
| 542 | } |
| 543 | return ptr; |
| 544 | }; |
| 545 | |
| 546 | const argc = this.argv.length; |
| 547 | |
| 548 | const argvPtrs = []; |
| 549 | this.argv.forEach((arg) => { |
| 550 | argvPtrs.push(strPtr(arg)); |
| 551 | }); |
| 552 | argvPtrs.push(0); |
| 553 | |
| 554 | const keys = Object.keys(this.env).sort(); |
| 555 | keys.forEach((key) => { |
| 556 | argvPtrs.push(strPtr(`${key}=${this.env[key]}`)); |
| 557 | }); |
| 558 | argvPtrs.push(0); |
| 559 | |
| 560 | const argv = offset; |
| 561 | argvPtrs.forEach((ptr) => { |
| 562 | this.mem.setUint32(offset, ptr, true); |