static bool DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t funcIndex) { int64_t before = PRMJ_Now(); uint32_t bodySize; if (!d.readVarU32(&bodySize)) return Fail(cx, d, "expected number of function body bytes"); if (d.bytesRemain() < bodySize) return Fail(cx, d, "function body length too big"); const uint8_t* bodyBegin = d.currentPosition(); const uint8_t* bodyEnd = bodyBegin + bodySize; FunctionGenerator fg; if (!mg.startFuncDef(d.currentOffset(), &fg)) return false; ValTypeVector locals; if (!locals.appendAll(mg.funcSig(funcIndex).args())) return false; if (!DecodeLocalEntries(d, &locals)) return Fail(cx, d, "failed decoding local entries"); for (ValType type : locals) { if (!CheckValType(cx, d, type)) return false; } FunctionDecoder f(cx, d, mg, fg, funcIndex, locals); ExprType type = ExprType::Void; while (d.currentPosition() < bodyEnd) { if (!DecodeExpr(f, &type)) return false; } if (!CheckType(f, type, f.sig().ret())) return false; if (d.currentPosition() != bodyEnd) return Fail(cx, d, "function body length mismatch"); if (!fg.bytes().resize(bodySize)) return false; memcpy(fg.bytes().begin(), bodyBegin, bodySize); int64_t after = PRMJ_Now(); unsigned generateTime = (after - before) / PRMJ_USEC_PER_MSEC; return mg.finishFuncDef(funcIndex, generateTime, &fg); }
static bool DecodeFuncBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, FunctionGenerator& fg, uint32_t funcIndex) { const uint8_t* bodyBegin = d.currentPosition(); FunctionDecoder f(cx, d, mg, fg, funcIndex); if (!DecodeExpr(f, f.ret())) return false; const uint8_t* bodyEnd = d.currentPosition(); uintptr_t bodyLength = bodyEnd - bodyBegin; if (!fg.bytecode().resize(bodyLength)) return false; PodCopy(fg.bytecode().begin(), bodyBegin, bodyLength); return true; }
bool waitForBytes(size_t numBytes) { numBytes = Min(numBytes, d_.bytesRemain()); const uint8_t* requiredEnd = d_.currentPosition() + numBytes; auto streamEnd = streamEnd_.lock(); while (streamEnd < requiredEnd) { if (cancelled_) return false; streamEnd.wait(); } return true; }