bool SavedStacks::insertFrames(JSContext *cx, ScriptFrameIter &iter, MutableHandle<SavedFrame*> frame) { if (iter.done()) { frame.set(nullptr); return true; } ScriptFrameIter thisFrame(iter); Rooted<SavedFrame*> parentFrame(cx); if (!insertFrames(cx, ++iter, &parentFrame)) return false; RootedScript script(cx, thisFrame.script()); RootedFunction callee(cx, thisFrame.maybeCallee()); const char *filename = script->filename(); RootedAtom source(cx, Atomize(cx, filename, strlen(filename))); if (!source) return false; uint32_t column; uint32_t line = PCToLineNumber(script, thisFrame.pc(), &column); SavedFrame::Lookup lookup(source, line, column, callee ? callee->displayAtom() : nullptr, parentFrame, thisFrame.compartment()->principals); frame.set(getOrCreateSavedFrame(cx, lookup)); return frame.address() != nullptr; }
void cmuk::computeVelocities(const DState& state, const XformCache& cache, const vec3f& roffs, vec3f linvel[], vec3f angvel[]) const { if (!linvel || !angvel) { return; } vec3f woffs = cache.absXforms[0].rotFwd() * roffs; linvel[0] = state.body_vel + vec3f::cross(angvel[0], -woffs); angvel[0] = state.body_angvel; for (int i=0; i<NUM_LEGS; ++i) { static const vec3f raxis[3] = { vec3f(1, 0, 0), vec3f(0, 1, 0), vec3f(0, 1, 0) }; for (int j=0; j<4; ++j) { int fidx = FRAME_FL_HIP_RX + 4*i + j; int pidx = parentFrame(fidx); const Transform3f& t0 = cache.absXforms[pidx]; const Transform3f& t1 = cache.absXforms[fidx]; const vec3f& x0 = t0.translation(); const vec3f& x1 = t1.translation(); vec3f d = x1 - x0; if (pidx == 0) { d -= woffs; } linvel[fidx] = linvel[pidx] + vec3f::cross(angvel[pidx], d); if (j < 3) { vec3f v = t0.rotFwd() * raxis[j]; angvel[fidx] = angvel[pidx] + state.leg_rotvel[i][j] * v; } else { angvel[fidx] = angvel[pidx]; } } } }
abstract_vframe* blockOopClass::parentVFrame(frame* currentFrame, bool orNone) { frame* pf= parentFrame(currentFrame, orNone); return pf == NULL ? NULL : new_vframe(pf, desc()); }
CMUK_ERROR_CODE cmuk::getRelTransform( const cmuk::XformCache& cache, FrameIndex f0, FrameIndex f1, Transform3f* xform ) const { int if0 = int(f0); int if1 = int(f1); if (if0 != FRAME_GROUND && (if0 < 0 || if0 >= NUM_FRAMES)) { return CMUK_BAD_FRAME_INDEX; } if (if1 !=FRAME_GROUND && (if1 < 0 || if1 >= NUM_FRAMES)) { return CMUK_BAD_FRAME_INDEX; } if (!xform) { return CMUK_INSUFFICIENT_ARGUMENTS; } int leg0 = -1; int leg1 = -1; if (if0 > int(FRAME_TRUNK)) { leg0 = (if0 - 1) / 4; } if (if1 > int(FRAME_TRUNK)) { leg1 = (if0 - 1) / 4; } if (leg0 >= 0 && leg1 >= 0 && leg0 != leg1) { Transform3f t1, t2; CMUK_ERROR_CODE status; status = getRelTransform(cache, f0, FRAME_TRUNK, &t1); if (status != CMUK_OKAY) { return status; } status = getRelTransform(cache, FRAME_TRUNK, f1, &t2); if (status != CMUK_OKAY) { return status; } *xform = t1 * t2; return CMUK_OKAY; } if (if0 == if1) { *xform = Transform3f(); return CMUK_OKAY; } // if1 should be smaller than if0 bool swap = if0 < if1; if (swap) { int tmp = if0; if0 = if1; if1 = tmp; } Transform3f rval = cache.relXforms[if0]; if0 = parentFrame(if0); // now we are going to decrement if0 while (if1 < if0 && if0 > 0) { rval = rval * cache.relXforms[if0]; if0 = parentFrame(if0); } if (swap) { rval = rval.inverse(); } *xform = rval; return CMUK_OKAY; }
bool SavedStacks::insertFrames(JSContext *cx, FrameIter &iter, MutableHandleSavedFrame frame, unsigned maxFrameCount) { // In order to lookup a cached SavedFrame object, we need to have its parent // SavedFrame, which means we need to walk the stack from oldest frame to // youngest. However, FrameIter walks the stack from youngest frame to // oldest. The solution is to append stack frames to a vector as we walk the // stack with FrameIter, and then do a second pass through that vector in // reverse order after the traversal has completed and get or create the // SavedFrame objects at that time. // // To avoid making many copies of FrameIter (whose copy constructor is // relatively slow), we save the subset of FrameIter's data that is relevant // to our needs in a FrameState object, and maintain a vector of FrameState // objects instead of a vector of FrameIter objects. // Accumulate the vector of FrameState objects in |stackState|. AutoFrameStateVector stackState(cx); while (!iter.done()) { AutoLocationValueRooter location(cx); { AutoCompartment ac(cx, iter.compartment()); if (!cx->compartment()->savedStacks().getLocation(cx, iter, &location)) return false; } { FrameState frameState(iter); frameState.location = location.get(); if (!stackState->append(frameState)) return false; } ++iter; if (maxFrameCount == 0) { // If maxFrameCount is zero, then there's no limit on the number of // frames. continue; } else if (maxFrameCount == 1) { // Since we were only asked to save one frame, do not continue // walking the stack and saving frame state. break; } else { maxFrameCount--; } } // Iterate through |stackState| in reverse order and get or create the // actual SavedFrame instances. RootedSavedFrame parentFrame(cx, nullptr); for (size_t i = stackState->length(); i != 0; i--) { SavedFrame::AutoLookupRooter lookup(cx, stackState[i-1].location.source, stackState[i-1].location.line, stackState[i-1].location.column, stackState[i-1].name, parentFrame, stackState[i-1].principals); parentFrame.set(getOrCreateSavedFrame(cx, lookup)); if (!parentFrame) return false; } frame.set(parentFrame); return true; }