Пример #1
0
static void rattr(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
{
    int data = verb & 31;
    verb >>= 5;

    int nameIndex, valueIndex;

    switch (verb) {
    case kAttr_Value_Value_Verb:
        nameIndex = rec.fNextName;      // record before the ++
        set(rec.fNames, rec.fNextName++, s, data);
        valueIndex = rec.fNextValue;    // record before the ++
        set(rec.fValues, rec.fNextValue++, s, 31);
        break;
    case kAttr_Value_Index_Verb:
        nameIndex = rec.fNextName;      // record before the ++
        set(rec.fNames, rec.fNextName++, s, data);
        valueIndex = rbyte(s);
        break;
    case kAttr_Index_Value_Verb:
        nameIndex = rdata(s, data);
        valueIndex = rec.fNextValue;    // record before the ++
        set(rec.fValues, rec.fNextValue++, s, 31);
        break;
    case kAttr_Index_Index_Verb:
        nameIndex = rdata(s, data);
        valueIndex = rbyte(s);
        break;
    default:
        SkDEBUGFAIL("bad verb");
        return;
    }
    writer.addAttribute(rec.fNames[nameIndex], rec.fValues[valueIndex]);
}
Пример #2
0
static int rdata(SkStream& s, int data)
{
    SkASSERT((data & ~31) == 0);
    if (data == 31)
    {
        data = rbyte(s);
        if (data == 0xFF)
        {
            data = rbyte(s);
            data = (data << 8) | rbyte(s);
        }
    }
    return data;
}
Пример #3
0
void addDbgGuardImpl(SrcKey sk) {
  Asm a { tx64->mainCode };

  // Emit the checks for debugger attach
  emitTLSLoad<ThreadInfo>(a, ThreadInfo::s_threadInfo, reg::rAsm);
  a.   load_reg64_disp_reg32(reg::rAsm, dbgOff, reg::rAsm);
  a.   testb((int8_t)0xff, rbyte(reg::rAsm));

  // Branch to a special REQ_INTERPRET if attached
  TCA fallback =
    emitServiceReq(tx64->stubsCode, REQ_INTERPRET, sk.offset(), 0);
  a. jnz(fallback);
}
Пример #4
0
/*
 * Read 32 bits of data + 8 bit checksum from the
 * DHT sensor. Returns relative humidity and
 * temperature in Celcius when successful. The
 * function returns zero if there was a checksum
 * error.
 */
static int
rsensor(int *relhumidity,int *celsius) {
	unsigned char u[5], cs = 0, x;

	for ( x=0; x<5; ++x ) {
		u[x] = rbyte();
		if ( x < 4 )		/* Only checksum data.. */
			cs += u[x];	/* Checksum */
	}

	if ( (cs & 0xFF)  == u[4] ) {
		*relhumidity = (int)u[0];
		*celsius   = (int)u[2];
		return 1;
	}
	return 0;
}
Пример #5
0
static void relem(unsigned verb, SkStream& s, BMLW& rec, SkXMLWriter& writer)
{
    int data = verb & 31;
    verb >>= 5;

    int elemIndex;

    if (verb == kStartElem_Value_Verb)
    {
        elemIndex = rec.fNextElem;      // record before the ++
        set(rec.fElems, rec.fNextElem++, s, data);
    }
    else
    {
        SkASSERT(verb == kStartElem_Index_Verb);
        elemIndex = rdata(s, data);
    }

    writer.startElement(rec.fElems[elemIndex]);

    for (;;)
    {
        verb = rbyte(s);
        switch (verb >> 5) {
        case kAttr_Value_Value_Verb:
        case kAttr_Value_Index_Verb:
        case kAttr_Index_Value_Verb:
        case kAttr_Index_Index_Verb:
            rattr(verb, s, rec, writer);
            break;
        case kStartElem_Value_Verb:
        case kStartElem_Index_Verb:
            relem(verb, s, rec, writer);
            break;
        case kEndElem_Verb:
            writer.endElement();
            return;
        default:
            SkDEBUGFAIL("bad verb");
        }
    }
}
Пример #6
0
/*
 * Service request stub emitter.
 *
 * Emit a service request stub of type `sr' at `start' in `cb'.
 */
void emit_svcreq(CodeBlock& cb,
                 TCA start,
                 bool persist,
                 folly::Optional<FPInvOffset> spOff,
                 ServiceRequest sr,
                 const ArgVec& argv) {
  FTRACE(2, "svcreq @{} {}(", start, to_name(sr));

  auto const is_reused = start != cb.frontier();

  CodeBlock stub;
  stub.init(start, stub_size(), "svcreq_stub");

  { Vauto vasm{stub};
    auto& v = vasm.main();

    // If we have an spOff, materialize rvmsp() so that handleSRHelper() can do
    // a VM reg sync.  (When we don't have an spOff, the caller of the service
    // request was responsible for making sure rvmsp already contained the top
    // of the stack.)
    if (spOff) {
      v << lea{rvmfp()[-cellsToBytes(spOff->offset)], rvmsp()};
    }

    auto live_out = leave_trace_regs();

    assert(argv.size() <= kMaxArgs);

    // Pick up CondCode arguments first---vasm may optimize immediate loads
    // into operations which clobber status flags.
    for (auto i = 0; i < argv.size(); ++i) {
      auto const& arg = argv[i];
      if (arg.kind != Arg::Kind::CondCode) continue;

      FTRACE(2, "c({}), ", cc_names[arg.cc]);
      v << setcc{arg.cc, r_svcreq_sf(), rbyte(r_svcreq_arg(i))};
    }

    for (auto i = 0; i < argv.size(); ++i) {
      auto const& arg = argv[i];
      auto const r = r_svcreq_arg(i);

      switch (arg.kind) {
        case Arg::Kind::Immed:
          FTRACE(2, "{}, ", arg.imm);
          v << copy{v.cns(arg.imm), r};
          break;
        case Arg::Kind::Address:
          FTRACE(2, "{}(%rip), ", arg.imm);
          v << leap{reg::rip[arg.imm], r};
          break;
        case Arg::Kind::CondCode:
          break;
      }
      live_out |= r;
    }
    FTRACE(2, ") : stub@");

    if (persist) {
      FTRACE(2, "<none>");
      v << copy{v.cns(0), r_svcreq_stub()};
    } else {
      FTRACE(2, "{}", stub.base());
      v << leap{reg::rip[int64_t(stub.base())], r_svcreq_stub()};
    }
    v << copy{v.cns(sr), r_svcreq_req()};

    live_out |= r_svcreq_stub();
    live_out |= r_svcreq_req();

    v << jmpi{TCA(handleSRHelper), live_out};

    // We pad ephemeral stubs unconditionally.  This is required for
    // correctness by the x64 code relocator.
    vasm.unit().padding = !persist;
  }

  if (!is_reused) cb.skip(stub.used());
}
Пример #7
0
void BML_XMLParser::Read(SkStream& s, SkXMLWriter& writer)
{
    BMLW rec;
    writer.writeHeader();
    relem(rbyte(s), s, rec, writer);
}
Пример #8
0
TCA
emitServiceReqWork(CodeBlock& cb, TCA start, bool persist, SRFlags flags,
                   ServiceRequest req, const ServiceReqArgVec& argv) {
  assert(start);
  const bool align = flags & SRFlags::Align;
  Asm as { cb };

  /*
   * Remember previous state of the code cache.
   */
  folly::Optional<CodeCursor> maybeCc = folly::none;
  if (start != as.frontier()) {
    maybeCc.emplace(cb, start);
  }

  /* max space for moving to align, saving VM regs plus emitting args */
  static const int
    kVMRegSpace = 0x14,
    kMovSize = 0xa,
    kNumServiceRegs = sizeof(serviceReqArgRegs) / sizeof(PhysReg),
    kMaxStubSpace = kJmpTargetAlign - 1 + kVMRegSpace +
      kNumServiceRegs * kMovSize;
  if (align) {
    moveToAlign(cb);
  }
  TCA retval = as.frontier();
  TRACE(3, "Emit Service Req @%p %s(", start, serviceReqName(req));
  /*
   * Move args into appropriate regs. Eager VMReg save may bash flags,
   * so set the CondCode arguments first.
   */
  for (int i = 0; i < argv.size(); ++i) {
    assert(i < kNumServiceReqArgRegs);
    auto reg = serviceReqArgRegs[i];
    const auto& argInfo = argv[i];
    switch(argv[i].m_kind) {
      case ServiceReqArgInfo::Immediate: {
        TRACE(3, "%" PRIx64 ", ", argInfo.m_imm);
        as.    emitImmReg(argInfo.m_imm, reg);
      } break;
      case ServiceReqArgInfo::CondCode: {
        // Already set before VM reg save.
        DEBUG_ONLY TCA start = as.frontier();
        as.    setcc(argInfo.m_cc, rbyte(reg));
        assert(start - as.frontier() <= kMovSize);
        TRACE(3, "cc(%x), ", argInfo.m_cc);
      } break;
      default: not_reached();
    }
  }
  emitEagerVMRegSave(as, RegSaveFlags::SaveFP);
  if (persist) {
    as.  emitImmReg(0, JIT::X64::rAsm);
  } else {
    as.  emitImmReg((uint64_t)start, JIT::X64::rAsm);
  }
  TRACE(3, ")\n");
  as.    emitImmReg(req, JIT::reg::rdi);

  /*
   * Weird hand-shaking with enterTC: reverse-call a service routine.
   *
   * In the case of some special stubs (m_callToExit, m_retHelper), we
   * have already unbalanced the return stack by doing a ret to
   * something other than enterTCHelper.  In that case
   * SRJmpInsteadOfRet indicates to fake the return.
   */
  if (flags & SRFlags::JmpInsteadOfRet) {
    as.  pop(JIT::reg::rax);
    as.  jmp(JIT::reg::rax);
  } else {
    as.  ret();
  }

  // TODO(2796856): we should record an OpServiceRequest pseudo-bytecode here.

  if (debug) {
    // not reached
    as.ud2();
  }

  if (!persist) {
    /*
     * Recycled stubs need to be uniformly sized. Make space for the
     * maximal possible service requests.
     */
    assert(as.frontier() - start <= kMaxStubSpace);
    as.emitNop(start + kMaxStubSpace - as.frontier());
    assert(as.frontier() - start == kMaxStubSpace);
  }
  return retval;
}