summaryrefslogtreecommitdiff
path: root/js/main.ts
blob: d035f9ba6d615b9600fb376dc3714dcd04fe1c81 (plain)
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
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
import { flatbuffers } from "flatbuffers";
import { deno as fbs } from "gen/msg_generated";
import { assert, log, assignCmdId } from "./util";
import * as util from "./util";
import * as os from "./os";
import * as runtime from "./runtime";
import { libdeno } from "./globals";
import * as timers from "./timers";
import { onFetchRes } from "./fetch";

function startMsg(cmdId: number): Uint8Array {
  const builder = new flatbuffers.Builder();
  fbs.Start.startStart(builder);
  const startOffset = fbs.Start.endStart(builder);
  fbs.Base.startBase(builder);
  fbs.Base.addCmdId(builder, cmdId);
  fbs.Base.addMsg(builder, startOffset);
  fbs.Base.addMsgType(builder, fbs.Any.Start);
  builder.finish(fbs.Base.endBase(builder));
  return builder.asUint8Array();
}

function onMessage(ui8: Uint8Array) {
  const bb = new flatbuffers.ByteBuffer(ui8);
  const base = fbs.Base.getRootAsBase(bb);
  switch (base.msgType()) {
    case fbs.Any.FetchRes: {
      const msg = new fbs.FetchRes();
      assert(base.msg(msg) != null);
      onFetchRes(base, msg);
      break;
    }
    case fbs.Any.TimerReady: {
      const msg = new fbs.TimerReady();
      assert(base.msg(msg) != null);
      timers.onMessage(msg);
      break;
    }
    default: {
      assert(false, "Unhandled message type");
      break;
    }
  }
}

/* tslint:disable-next-line:no-default-export */
export default function denoMain() {
  libdeno.recv(onMessage);
  runtime.setup();

  // First we send an empty "Start" message to let the privlaged side know we
  // are ready. The response should be a "StartRes" message containing the CLI
  // argv and other info.
  const cmdId = assignCmdId();
  const res = libdeno.send(startMsg(cmdId));

  // TODO(ry) Remove this conditional once main.rs gets up to speed.
  if (res == null) {
    console.log(`The 'Start' message got a null response.  Normally this would
    be an error but main.rs currently does this."); Exiting without error.`);
    return;
  }

  // Deserialize res into startResMsg.
  const bb = new flatbuffers.ByteBuffer(res);
  const base = fbs.Base.getRootAsBase(bb);
  assert(fbs.Any.StartRes === base.msgType());
  const startResMsg = new fbs.StartRes();
  assert(base.msg(startResMsg) != null);

  util.setLogDebug(startResMsg.debugFlag());

  const cwd = startResMsg.cwd();
  log("cwd", cwd);

  const argv: string[] = [];
  for (let i = 0; i < startResMsg.argvLength(); i++) {
    argv.push(startResMsg.argv(i));
  }
  log("argv", argv);

  const inputFn = argv[1];
  if (!inputFn) {
    console.log("No input script specified.");
    os.exit(1);
  }

  const mod = runtime.resolveModule(inputFn, `${cwd}/`);
  assert(mod != null);
  // TypeScript does not track assert, therefore not null assertion
  mod!.compileAndRun();
}