run method

List<double> run(
  1. List<List<double>> slots
)

The value, given each of inputs' components in order.

Implementation

List<double> run(List<List<double>> slots) {
  final r = _registers;
  for (var i = 0; i < inputs.length; i++) {
    final input = inputs[i];
    final value = slots[i];
    for (var lane = 0; lane < input.width; lane++) {
      r[input.lane + lane] = value[lane];
    }
  }
  for (var pc = 0; pc < code.length; pc += 8) {
    final op = code[pc];
    final width = code[pc + 1] & 0xFF;
    final flags = code[pc + 1] >> 8;
    final dst = code[pc + 2];
    final a = code[pc + 3];
    final b = code[pc + 4];
    final c = code[pc + 5];
    // How far each operand moves per lane: nought when its flag spreads
    // one lane across the width.
    final sa = flags & 1 != 0 ? 0 : 1;
    final sb = flags & 2 != 0 ? 0 : 1;
    final sc = flags & 4 != 0 ? 0 : 1;
    switch (op) {
      case ExpressionOp.loadConstant:
        for (var i = 0; i < width; i++) {
          r[dst + i] = constants[a + i];
        }
      case ExpressionOp.move:
        for (var i = 0; i < width; i++) {
          r[dst + i] = r[a + i];
        }
      case ExpressionOp.swizzle:
        for (var i = 0; i < width; i++) {
          r[dst + i] = r[a + ((b >> (2 * i)) & 3)];
        }
      case ExpressionOp.negate:
        for (var i = 0; i < width; i++) {
          r[dst + i] = -r[a + i];
        }
      case ExpressionOp.not:
        r[dst] = r[a] != 0 ? 0 : 1;
      // Each operator as `expressionOperatorAt` computes it, written out
      // under its own opcode: no symbol is looked up and no string is
      // compared per lane.
      case ExpressionOp.add:
        for (var i = 0; i < width; i++) {
          r[dst + i] = r[a + i * sa] + r[b + i * sb];
        }
      case ExpressionOp.subtract:
        for (var i = 0; i < width; i++) {
          r[dst + i] = r[a + i * sa] - r[b + i * sb];
        }
      case ExpressionOp.multiply:
        for (var i = 0; i < width; i++) {
          r[dst + i] = r[a + i * sa] * r[b + i * sb];
        }
      case ExpressionOp.divide:
        for (var i = 0; i < width; i++) {
          r[dst + i] = r[a + i * sa] / r[b + i * sb];
        }
      case ExpressionOp.less:
        r[dst] = r[a] < r[b] ? 1.0 : 0.0;
      case ExpressionOp.lessEqual:
        r[dst] = r[a] <= r[b] ? 1.0 : 0.0;
      case ExpressionOp.greater:
        r[dst] = r[a] > r[b] ? 1.0 : 0.0;
      case ExpressionOp.greaterEqual:
        r[dst] = r[a] >= r[b] ? 1.0 : 0.0;
      case ExpressionOp.equal:
        r[dst] = r[a] == r[b] ? 1.0 : 0.0;
      case ExpressionOp.notEqual:
        r[dst] = r[a] != r[b] ? 1.0 : 0.0;
      case ExpressionOp.and:
        r[dst] = r[a] != 0 && r[b] != 0 ? 1.0 : 0.0;
      case ExpressionOp.or:
        r[dst] = r[a] != 0 || r[b] != 0 ? 1.0 : 0.0;
      case ExpressionOp.select:
        for (var i = 0; i < width; i++) {
          r[dst + i] = r[a] != 0 ? r[b + i] : r[c + i];
        }
      case ExpressionOp.dot:
        var sum = 0.0;
        for (var i = 0; i < width; i++) {
          sum += r[a + i] * r[b + i];
        }
        r[dst] = sum;
      case ExpressionOp.length:
        var sum = 0.0;
        for (var i = 0; i < width; i++) {
          sum += r[a + i] * r[a + i];
        }
        r[dst] = math.sqrt(sum);
      case ExpressionOp.normalize:
        var sum = 0.0;
        for (var i = 0; i < width; i++) {
          sum += r[a + i] * r[a + i];
        }
        final length = math.sqrt(sum);
        for (var i = 0; i < width; i++) {
          r[dst + i] = length == 0 ? 0 : r[a + i] / length;
        }
      case ExpressionOp.mix:
        for (var i = 0; i < width; i++) {
          r[dst + i] = mixAt(r[a + i * sa], r[b + i * sb], r[c + i * sc]);
        }
      case ExpressionOp.clamp:
        for (var i = 0; i < width; i++) {
          r[dst + i] = clampAt(r[a + i * sa], r[b + i * sb], r[c + i * sc]);
        }
      case ExpressionOp.smoothstep:
        for (var i = 0; i < width; i++) {
          r[dst + i] = smoothstepAt(
            r[a + i * sa],
            r[b + i * sb],
            r[c + i * sc],
          );
        }
      case ExpressionOp.step:
        for (var i = 0; i < width; i++) {
          r[dst + i] = stepAt(r[a + i * sa], r[b + i * sb]);
        }
      case ExpressionOp.pow:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.pow(r[a + i * sa], r[b + i * sb]);
        }
      case ExpressionOp.min:
        for (var i = 0; i < width; i++) {
          r[dst + i] = minAt(r[a + i * sa], r[b + i * sb]);
        }
      case ExpressionOp.max:
        for (var i = 0; i < width; i++) {
          r[dst + i] = maxAt(r[a + i * sa], r[b + i * sb]);
        }
      case ExpressionOp.atan2:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.atan2(r[a + i * sa], r[b + i * sb]);
        }
      case ExpressionOp.abs:
        for (var i = 0; i < width; i++) {
          r[dst + i] = absAt(r[a + i]);
        }
      case ExpressionOp.sqrt:
        for (var i = 0; i < width; i++) {
          r[dst + i] = math.sqrt(r[a + i]);
        }
      case ExpressionOp.floor:
        for (var i = 0; i < width; i++) {
          r[dst + i] = floorAt(r[a + i]);
        }
      case ExpressionOp.fract:
        for (var i = 0; i < width; i++) {
          r[dst + i] = fractAt(r[a + i]);
        }
      case ExpressionOp.sin:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.sin(r[a + i]);
        }
      case ExpressionOp.cos:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.cos(r[a + i]);
        }
      case ExpressionOp.tan:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.tan(r[a + i]);
        }
      case ExpressionOp.asin:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.asin(r[a + i]);
        }
      case ExpressionOp.acos:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.acos(r[a + i]);
        }
      case ExpressionOp.atan:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.atan(r[a + i]);
        }
      case ExpressionOp.exp:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.exp(r[a + i]);
        }
      case ExpressionOp.log:
        for (var i = 0; i < width; i++) {
          r[dst + i] = Portable.log(r[a + i]);
        }
      case ExpressionOp.sign:
        for (var i = 0; i < width; i++) {
          r[dst + i] = signAt(r[a + i]);
        }
      default:
        throw StateError('no opcode $op');
    }
  }
  return <double>[for (var i = 0; i < resultWidth; i++) r[resultLane + i]];
}