//------------------------------array_store_check------------------------------ // pull array from stack and check that the store is valid void Parse::array_store_check() { // Shorthand access to array store elements Node *obj = stack(_sp-1); Node *idx = stack(_sp-2); Node *ary = stack(_sp-3); if (_gvn.type(obj) == TypePtr::NULL_PTR) { // There's never a type check on null values. // This cutout lets us avoid the uncommon_trap(Reason_array_check) // below, which turns into a performance liability if the // gen_checkcast folds up completely. return; } // Extract the array klass type int klass_offset = oopDesc::klass_offset_in_bytes(); Node* p = basic_plus_adr( ary, ary, klass_offset ); // p's type is array-of-OOPS plus klass_offset Node* array_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS) ); // Get the array klass const TypeKlassPtr *tak = _gvn.type(array_klass)->is_klassptr(); // array_klass's type is generally INexact array-of-oop. Heroically // cast the array klass to EXACT array and uncommon-trap if the cast // fails. bool always_see_exact_class = false; if (MonomorphicArrayCheck && !too_many_traps(Deoptimization::Reason_array_check)) { always_see_exact_class = true; // (If no MDO at all, hope for the best, until a trap actually occurs.) } // Is the array klass is exactly its defined type? if (always_see_exact_class && !tak->klass_is_exact()) { // Make a constant out of the inexact array klass const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr(); Node* con = makecon(extak); Node* cmp = _gvn.transform(new (C, 3) CmpPNode( array_klass, con )); Node* bol = _gvn.transform(new (C, 2) BoolNode( cmp, BoolTest::eq )); Node* ctrl= control(); { BuildCutout unless(this, bol, PROB_MAX); uncommon_trap(Deoptimization::Reason_array_check, Deoptimization::Action_maybe_recompile, tak->klass()); } if (stopped()) { // MUST uncommon-trap? set_control(ctrl); // Then Don't Do It, just fall into the normal checking } else { // Cast array klass to exactness: // Use the exact constant value we know it is. replace_in_map(array_klass,con); CompileLog* log = C->log(); if (log != NULL) { log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'", log->identify(tak->klass())); } array_klass = con; // Use cast value moving forward } } // Come here for polymorphic array klasses // Extract the array element class int element_klass_offset = objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc); Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset); Node *a_e_klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p2, tak) ); // Check (the hard way) and throw if not a subklass. // Result is ignored, we just need the CFG effects. gen_checkcast( obj, a_e_klass ); }
static int vector3_normalize(lua_State* L) { LuaStack stack(L); stack.push_vector3(normalize(stack.get_vector3(1))); return 1; }
static int vector3_forward(lua_State* L) { LuaStack stack(L); stack.push_vector3(VECTOR3_FORWARD); return 1; }
static int vector3_equal(lua_State* L) { LuaStack stack(L); stack.push_bool(stack.get_vector3(1) == stack.get_vector3(2)); return 1; }
static int vector3_squared_length(lua_State* L) { LuaStack stack(L); stack.push_float(squared_length(stack.get_vector3(1))); return 1; }
/// @par /// /// See the #rcConfig documentation for more information on the configuration parameters. /// /// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf, const float sampleDist, const float sampleMaxError, rcPolyMeshDetail& dmesh) { rcAssert(ctx); ctx->startTimer(RC_TIMER_BUILD_POLYMESHDETAIL); if (mesh.nverts == 0 || mesh.npolys == 0) return true; const int nvp = mesh.nvp; const float cs = mesh.cs; const float ch = mesh.ch; const float* orig = mesh.bmin; const int borderSize = mesh.borderSize; rcIntArray edges(64); rcIntArray tris(512); rcIntArray stack(512); rcIntArray samples(512); float verts[256*3]; rcHeightPatch hp; int nPolyVerts = 0; int maxhw = 0, maxhh = 0; rcScopedDelete<int> bounds = (int*)rcAlloc(sizeof(int)*mesh.npolys*4, RC_ALLOC_TEMP); if (!bounds) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'bounds' (%d).", mesh.npolys*4); return false; } rcScopedDelete<float> poly = (float*)rcAlloc(sizeof(float)*nvp*3, RC_ALLOC_TEMP); if (!poly) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'poly' (%d).", nvp*3); return false; } // Find max size for a polygon area. for (int i = 0; i < mesh.npolys; ++i) { const unsigned short* p = &mesh.polys[i*nvp*2]; int& xmin = bounds[i*4+0]; int& xmax = bounds[i*4+1]; int& ymin = bounds[i*4+2]; int& ymax = bounds[i*4+3]; xmin = chf.width; xmax = 0; ymin = chf.height; ymax = 0; for (int j = 0; j < nvp; ++j) { if(p[j] == RC_MESH_NULL_IDX) break; const unsigned short* v = &mesh.verts[p[j]*3]; xmin = rcMin(xmin, (int)v[0]); xmax = rcMax(xmax, (int)v[0]); ymin = rcMin(ymin, (int)v[2]); ymax = rcMax(ymax, (int)v[2]); nPolyVerts++; } xmin = rcMax(0,xmin-1); xmax = rcMin(chf.width,xmax+1); ymin = rcMax(0,ymin-1); ymax = rcMin(chf.height,ymax+1); if (xmin >= xmax || ymin >= ymax) continue; maxhw = rcMax(maxhw, xmax-xmin); maxhh = rcMax(maxhh, ymax-ymin); } hp.data = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxhw*maxhh, RC_ALLOC_TEMP); if (!hp.data) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'hp.data' (%d).", maxhw*maxhh); return false; } dmesh.nmeshes = mesh.npolys; dmesh.nverts = 0; dmesh.ntris = 0; dmesh.meshes = (unsigned int*)rcAlloc(sizeof(unsigned int)*dmesh.nmeshes*4, RC_ALLOC_PERM); if (!dmesh.meshes) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.meshes' (%d).", dmesh.nmeshes*4); return false; } int vcap = nPolyVerts+nPolyVerts/2; int tcap = vcap*2; dmesh.nverts = 0; dmesh.verts = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM); if (!dmesh.verts) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", vcap*3); return false; } dmesh.ntris = 0; dmesh.tris = (unsigned char*)rcAlloc(sizeof(unsigned char*)*tcap*4, RC_ALLOC_PERM); if (!dmesh.tris) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4); return false; } for (int i = 0; i < mesh.npolys; ++i) { const unsigned short* p = &mesh.polys[i*nvp*2]; // Store polygon vertices for processing. int npoly = 0; for (int j = 0; j < nvp; ++j) { if(p[j] == RC_MESH_NULL_IDX) break; const unsigned short* v = &mesh.verts[p[j]*3]; poly[j*3+0] = v[0]*cs; poly[j*3+1] = v[1]*ch; poly[j*3+2] = v[2]*cs; npoly++; } // Get the height data from the area of the polygon. hp.xmin = bounds[i*4+0]; hp.ymin = bounds[i*4+2]; hp.width = bounds[i*4+1]-bounds[i*4+0]; hp.height = bounds[i*4+3]-bounds[i*4+2]; getHeightData(chf, p, npoly, mesh.verts, borderSize, hp, stack); // Build detail mesh. int nverts = 0; if (!buildPolyDetail(ctx, poly, npoly, sampleDist, sampleMaxError, chf, hp, verts, nverts, tris, edges, samples)) { return false; } // Move detail verts to world space. for (int j = 0; j < nverts; ++j) { verts[j*3+0] += orig[0]; verts[j*3+1] += orig[1] + chf.ch; // Is this offset necessary? verts[j*3+2] += orig[2]; } // Offset poly too, will be used to flag checking. for (int j = 0; j < npoly; ++j) { poly[j*3+0] += orig[0]; poly[j*3+1] += orig[1]; poly[j*3+2] += orig[2]; } // Store detail submesh. const int ntris = tris.size()/4; dmesh.meshes[i*4+0] = (unsigned int)dmesh.nverts; dmesh.meshes[i*4+1] = (unsigned int)nverts; dmesh.meshes[i*4+2] = (unsigned int)dmesh.ntris; dmesh.meshes[i*4+3] = (unsigned int)ntris; // Store vertices, allocate more memory if necessary. if (dmesh.nverts+nverts > vcap) { while (dmesh.nverts+nverts > vcap) vcap += 256; float* newv = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM); if (!newv) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newv' (%d).", vcap*3); return false; } if (dmesh.nverts) memcpy(newv, dmesh.verts, sizeof(float)*3*dmesh.nverts); rcFree(dmesh.verts); dmesh.verts = newv; } for (int j = 0; j < nverts; ++j) { dmesh.verts[dmesh.nverts*3+0] = verts[j*3+0]; dmesh.verts[dmesh.nverts*3+1] = verts[j*3+1]; dmesh.verts[dmesh.nverts*3+2] = verts[j*3+2]; dmesh.nverts++; } // Store triangles, allocate more memory if necessary. if (dmesh.ntris+ntris > tcap) { while (dmesh.ntris+ntris > tcap) tcap += 256; unsigned char* newt = (unsigned char*)rcAlloc(sizeof(unsigned char)*tcap*4, RC_ALLOC_PERM); if (!newt) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newt' (%d).", tcap*4); return false; } if (dmesh.ntris) memcpy(newt, dmesh.tris, sizeof(unsigned char)*4*dmesh.ntris); rcFree(dmesh.tris); dmesh.tris = newt; } for (int j = 0; j < ntris; ++j) { const int* t = &tris[j*4]; dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0]; dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[1]; dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[2]; dmesh.tris[dmesh.ntris*4+3] = getTriFlags(&verts[t[0]*3], &verts[t[1]*3], &verts[t[2]*3], poly, npoly); dmesh.ntris++; } } ctx->stopTimer(RC_TIMER_BUILD_POLYMESHDETAIL); return true; }
static int vector3_divide(lua_State* L) { LuaStack stack(L); stack.push_vector3(stack.get_vector3(1) / stack.get_float(2)); return 1; }
nsresult nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo) { *aLoadInfo = nsnull; nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell)); NS_ENSURE_TRUE(docShell, NS_ERROR_NOT_AVAILABLE); nsresult rv; // Get JSContext from stack. nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); JSContext *cx; NS_ENSURE_SUCCESS(GetContextFromStack(stack, &cx), NS_ERROR_FAILURE); nsCOMPtr<nsISupports> owner; nsCOMPtr<nsIURI> sourceURI; if (cx) { // No cx means that there's no JS running, or at least no JS that // was run through code that properly pushed a context onto the // context stack (as all code that runs JS off of web pages // does). We won't bother with security checks in this case, but // we need to create the loadinfo etc. // Get security manager. nsCOMPtr<nsIScriptSecurityManager> secMan(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, rv); // Check to see if URI is allowed. rv = secMan->CheckLoadURIFromScript(cx, aURI); NS_ENSURE_SUCCESS(rv, rv); // Now get the principal to use when loading the URI // First, get the principal and frame. JSStackFrame *fp; nsIPrincipal* principal = secMan->GetCxSubjectPrincipalAndFrame(cx, &fp); NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE); nsCOMPtr<nsIURI> principalURI; principal->GetURI(getter_AddRefs(principalURI)); // Make the load's referrer reflect changes to the document's URI caused by // push/replaceState, if possible. First, get the document corresponding to // fp. If the document's original URI (i.e. its URI before // push/replaceState) matches the principal's URI, use the document's // current URI as the referrer. If they don't match, use the principal's // URI. nsCOMPtr<nsIDocument> frameDoc = GetFrameDocument(cx, fp); nsCOMPtr<nsIURI> docOriginalURI, docCurrentURI; if (frameDoc) { docOriginalURI = frameDoc->GetOriginalURI(); docCurrentURI = frameDoc->GetDocumentURI(); } bool urisEqual = false; if (docOriginalURI && docCurrentURI && principalURI) { principalURI->Equals(docOriginalURI, &urisEqual); } if (urisEqual) { sourceURI = docCurrentURI; } else { sourceURI = principalURI; } owner = do_QueryInterface(principal); } // Create load info nsCOMPtr<nsIDocShellLoadInfo> loadInfo; docShell->CreateLoadInfo(getter_AddRefs(loadInfo)); NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE); loadInfo->SetOwner(owner); if (sourceURI) { loadInfo->SetReferrer(sourceURI); } loadInfo.swap(*aLoadInfo); return NS_OK; }
bool rcBuildRegions(rcCompactHeightfield& chf, int borderSize, int minRegionSize, int mergeRegionSize) { rcTimeVal startTime = rcGetPerformanceTimer(); const int w = chf.width; const int h = chf.height; if (!chf.regs) { chf.regs = new unsigned short[chf.spanCount]; if (!chf.regs) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'chf.reg' (%d).", chf.spanCount); return false; } } rcScopedDelete<unsigned short> tmp = new unsigned short[chf.spanCount*4]; if (!tmp) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'tmp' (%d).", chf.spanCount*4); return false; } rcTimeVal regStartTime = rcGetPerformanceTimer(); rcIntArray stack(1024); rcIntArray visited(1024); unsigned short* srcReg = tmp; unsigned short* srcDist = tmp+chf.spanCount; unsigned short* dstReg = tmp+chf.spanCount*2; unsigned short* dstDist = tmp+chf.spanCount*3; memset(srcReg, 0, sizeof(unsigned short)*chf.spanCount); memset(srcDist, 0, sizeof(unsigned short)*chf.spanCount); unsigned short regionId = 1; unsigned short level = (chf.maxDistance+1) & ~1; // TODO: Figure better formula, expandIters defines how much the // watershed "overflows" and simplifies the regions. Tying it to // agent radius was usually good indication how greedy it could be. // const int expandIters = 4 + walkableRadius * 2; const int expandIters = 8; // Mark border regions. paintRectRegion(0, borderSize, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(w-borderSize, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(0, w, 0, borderSize, regionId|RC_BORDER_REG, chf, srcReg); regionId++; paintRectRegion(0, w, h-borderSize, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++; rcTimeVal expTime = 0; rcTimeVal floodTime = 0; while (level > 0) { level = level >= 2 ? level-2 : 0; rcTimeVal expStartTime = rcGetPerformanceTimer(); // Expand current regions until no empty connected cells found. if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { rcSwap(srcReg, dstReg); rcSwap(srcDist, dstDist); } expTime += rcGetPerformanceTimer() - expStartTime; rcTimeVal floodStartTime = rcGetPerformanceTimer(); // Mark new regions with IDs. for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { const rcCompactCell& c = chf.cells[x+y*w]; for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) { if (chf.dist[i] < level || srcReg[i] != 0 || chf.areas[i] == RC_NULL_AREA) continue; if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack)) regionId++; } } } floodTime += rcGetPerformanceTimer() - floodStartTime; } // Expand current regions until no empty connected cells found. if (expandRegions(expandIters*8, 0, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { rcSwap(srcReg, dstReg); rcSwap(srcDist, dstDist); } rcTimeVal regEndTime = rcGetPerformanceTimer(); rcTimeVal filterStartTime = rcGetPerformanceTimer(); // Filter out small regions. chf.maxRegions = regionId; if (!filterSmallRegions(minRegionSize, mergeRegionSize, chf.maxRegions, chf, srcReg)) return false; rcTimeVal filterEndTime = rcGetPerformanceTimer(); // Write the result out. memcpy(chf.regs, srcReg, sizeof(unsigned short)*chf.spanCount); rcTimeVal endTime = rcGetPerformanceTimer(); /* if (rcGetLog()) { rcGetLog()->log(RC_LOG_PROGRESS, "Build regions: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - reg: %.3f ms", rcGetDeltaTimeUsec(regStartTime, regEndTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - exp: %.3f ms", rcGetDeltaTimeUsec(0, expTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - flood: %.3f ms", rcGetDeltaTimeUsec(0, floodTime)/1000.0f); rcGetLog()->log(RC_LOG_PROGRESS, " - filter: %.3f ms", rcGetDeltaTimeUsec(filterStartTime, filterEndTime)/1000.0f); } */ if (rcGetBuildTimes()) { rcGetBuildTimes()->buildRegions += rcGetDeltaTimeUsec(startTime, endTime); rcGetBuildTimes()->buildRegionsReg += rcGetDeltaTimeUsec(regStartTime, regEndTime); rcGetBuildTimes()->buildRegionsExp += rcGetDeltaTimeUsec(0, expTime); rcGetBuildTimes()->buildRegionsFlood += rcGetDeltaTimeUsec(0, floodTime); rcGetBuildTimes()->buildRegionsFilter += rcGetDeltaTimeUsec(filterStartTime, filterEndTime); } return true; }
dtStatus dtBuildTileCacheRegions(dtTileCacheAlloc* alloc, const int minRegionArea, const int mergeRegionArea, dtTileCacheLayer& layer, dtTileCacheDistanceField dfield) { dtAssert(alloc); const int w = (int)layer.header->width; const int h = (int)layer.header->height; const int size = w*h; dtFixedArray<unsigned short> buf(alloc, size*4); if (!buf) { return DT_FAILURE | DT_OUT_OF_MEMORY; } dtIntArray stack(1024); dtIntArray visited(1024); unsigned short* srcReg = buf; unsigned short* srcDist = buf+size; unsigned short* dstReg = buf+size*2; unsigned short* dstDist = buf+size*3; memset(srcReg, 0, sizeof(unsigned short)*size); memset(srcDist, 0, sizeof(unsigned short)*size); unsigned short regionId = 1; unsigned short level = (dfield.maxDist+1) & ~1; // TODO: Figure better formula, expandIters defines how much the // watershed "overflows" and simplifies the regions. Tying it to // agent radius was usually good indication how greedy it could be. // const int expandIters = 4 + walkableRadius * 2; const int expandIters = 8; while (level > 0) { level = level >= 2 ? level-2 : 0; // Expand current regions until no empty connected cells found. if (expandRegions(expandIters, level, layer, dfield, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { dtSwap(srcReg, dstReg); dtSwap(srcDist, dstDist); } // Mark new regions with IDs. for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { const int i=x+y*w; if (dfield.data[i] < level || srcReg[i] != 0 || layer.areas[i] == DT_TILECACHE_NULL_AREA) continue; if (floodRegion(x, y, i, level, regionId, layer, dfield, srcReg, srcDist, stack)) regionId++; } } } // Expand current regions until no empty connected cells found. if (expandRegions(expandIters*8, 0, layer, dfield, srcReg, srcDist, dstReg, dstDist, stack) != srcReg) { dtSwap(srcReg, dstReg); dtSwap(srcDist, dstDist); } dtStatus status = filterSmallRegions(alloc, layer, minRegionArea, mergeRegionArea, regionId, srcReg); if (dtStatusFailed(status)) { return status; } // Write the result out. memcpy(layer.regs, srcReg, sizeof(unsigned short)*size); layer.regCount = regionId; return DT_SUCCESS; }
size_t ygen_emit::opgen( ygen_program* p, size_t index ) { yssa_function* function = p->ssafunc; yssa_opinst* op = function->ops.at( index ); switch ( op->opcode ) { case YL_NOP: { p->ops.emplace_back( YL_NOP, 0, 0, 0 ); p->slocs.push_back( op->sloc ); return 1; } case YL_MOV: { assert( op->result_count == 1 ); assert( op->operand_count == 1 ); if ( op->r != yl_opinst::NOVAL && op->r != op->operand[ 0 ]->r ) { unsigned a = op->operand[ 0 ]->r; assert( a != yl_opinst::NOVAL ); p->ops.emplace_back( (yl_opcode)op->opcode, op->r, a, 0 ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_NULL: case YL_NEG: case YL_BITNOT: case YL_MUL: case YL_DIV: case YL_MOD: case YL_INTDIV: case YL_ADD: case YL_SUB: case YL_LSL: case YL_LSR: case YL_ASR: case YL_BITAND: case YL_BITXOR: case YL_BITOR: case YL_CONCAT: case YL_EQ: case YL_NE: case YL_LT: case YL_GT: case YL_LE: case YL_GE: case YL_LNOT: case YL_LXOR: case YL_SUPER: case YL_INKEY: case YL_INDEX: case YL_RESPONDS: case YL_IS: { assert( op->result_count == 1 ); if ( op->r != yl_opinst::NOVAL ) { unsigned a = operand( op, 0 ); unsigned b = operand( op, 1 ); p->ops.emplace_back( (yl_opcode)op->opcode, op->r, a, b ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_BOOL: { assert( op->result_count == 1 ); if ( op->r != yl_opinst::NOVAL ) { unsigned a = op->boolean ? 1 : 0; p->ops.emplace_back( YL_BOOL, op->r, a, 0 ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_NUMBER: { assert( op->result_count == 1 ); if ( op->r != yl_opinst::NOVAL ) { unsigned c = (unsigned)p->numvals.at( op->number ); p->ops.emplace_back( YL_NUMBER, op->r, c ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_STRING: { assert( op->result_count == 1 ); if ( op->r != yl_opinst::NOVAL ) { symkey k( op->string->string, op->string->length ); unsigned c = (unsigned)p->strvals.at( k ); p->ops.emplace_back( YL_STRING, op->r, c ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_GLOBAL: { assert( op->result_count == 1 ); if ( op->r != yl_opinst::NOVAL ) { unsigned b = (unsigned)p->strvals.at( op->key ); p->ops.emplace_back( YL_GLOBAL, op->r, 0, b ); p->slocs.push_back( op->sloc ); p->ops.emplace_back( YL_ILCACHE, 0, (unsigned)( p->ilcount++ ) ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_SETGLOBAL: { assert( op->result_count == 0 ); unsigned r = operand( op, 0 ); unsigned b = (unsigned)p->strvals.at( op->key ); p->ops.emplace_back( YL_SETGLOBAL, r, 0, b ); p->slocs.push_back( op->sloc ); p->ops.emplace_back( YL_ILCACHE, 0, (unsigned)( p->ilcount++ ) ); p->slocs.push_back( op->sloc ); return 1; } case YL_FUNCTION: { if ( op->r != yl_opinst::NOVAL ) { unsigned c = (unsigned)p->funvals.at( op->function ); p->ops.emplace_back( YL_FUNCTION, op->r, c ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } size_t n; for ( n = 1; index + n < function->ops.size(); ++n ) { yssa_opinst* up = function->ops.at( index + n ); if ( up->opcode == YL_UPLOCAL ) { if ( op->r != yl_opinst::NOVAL ) { unsigned b = operand( up, 0 ); p->ops.emplace_back( YL_UPLOCAL, up->r, up->a, b ); p->slocs.push_back( op->sloc ); p->localupcount = std::max( p->localupcount, (size_t)up->a + 1 ); } } else if ( up->opcode == YL_UPUPVAL ) { if ( op->r != yl_opinst::NOVAL ) { p->ops.emplace_back( YL_UPUPVAL, up->r, up->a, 0 ); p->slocs.push_back( op->sloc ); } } else { break; } } return n; } case YL_VARARG: case YL_CALL: case YL_YCALL: case YL_YIELD: case YL_RETURN: case YL_NEXT: case YL_EXTEND: case YL_UNPACK: { assert( op->is_call() ); // These ops can either produce or consume multiple values. We must // treat chains of multivals as a single operation on top of stack. yssa_opinst* multival = op; yssa_opinst* firstop = op; yssa_opinst* finalop = op; size_t ilast = index + 1; for ( ; ilast < function->ops.size(); ++ilast ) { yssa_opinst* op = function->ops.at( ilast ); if ( op->opcode == YSSA_IMPLICIT ) { continue; } if ( op->is_call() && op->multival == multival ) { // Follow the multival chain. multival = op; finalop = op; continue; } // Multival results must be consumed by the next instruction. assert( ! op->has_multival() || ! op->multival ); break; } // Get all operands into the correct registers. ygen_movgraph arguments; for ( size_t iop = index; iop < ilast; ++iop ) { op = function->ops.at( iop ); if ( op->opcode == YSSA_IMPLICIT ) { continue; } // First argument of UNPACK and EXTEND can be any register. unsigned first = 0; if ( op->opcode == YL_UNPACK || op->opcode == YL_EXTEND ) { unsigned a = operand( op, first++ ); if ( a >= multival->stacktop ) { arguments.move( op->stacktop, a ); op->operand[ 0 ]->r = op->stacktop; } } // Move remaining operands. for ( unsigned iarg = first; iarg < op->operand_count; ++iarg ) { unsigned a = operand( op, iarg ); unsigned r = op->stacktop + iarg - first; arguments.move( r, a ); } } arguments.emit( p, firstop->sloc ); // Emit instructions. for ( size_t iop = index; iop < ilast; ++iop ) { op = function->ops.at( iop ); if ( op->opcode == YSSA_IMPLICIT ) { continue; } assert( op->is_call() ); assert( op->stacktop != yl_opinst::NOVAL ); switch ( op->opcode ) { case YL_VARARG: case YL_CALL: case YL_YCALL: case YL_YIELD: case YL_RETURN: { unsigned a = op->multival ? yl_opinst::MARK : op->operand_count; unsigned b = op->result_count; p->ops.emplace_back( (yl_opcode)op->opcode, op->stacktop, a, b ); p->slocs.push_back( op->sloc ); stack( p, op->stacktop, op->result_count ); break; } case YL_NEXT: { p->ops.emplace_back( YL_NEXT, op->stacktop, op->a, op->result_count ); p->slocs.push_back( op->sloc ); stack( p, op->stacktop, op->result_count ); break; } case YL_EXTEND: { unsigned a = op->multival ? yl_opinst::MARK : op->operand_count; unsigned b = operand( op, 0 ); p->ops.emplace_back( YL_EXTEND, op->stacktop, a, b ); p->slocs.push_back( op->sloc ); break; } case YL_UNPACK: { unsigned a = operand( op, 0 ); p->ops.emplace_back( YL_UNPACK, op->stacktop, a, op->result_count ); p->slocs.push_back( op->sloc ); stack( p, op->stacktop, op->result_count ); break; } default: assert( ! "unexpected multival operation" ); break; } } // Results of final op. op = finalop; assert( op->is_call() ); // RETURN and EXTEND don't return any results. if ( op->opcode == YL_RETURN || op->opcode == YL_EXTEND ) { assert( op->result_count == 0 ); return ilast - index; } // Move all results into the correct registers. ygen_movgraph results; if ( op->r != yl_opinst::NOVAL ) { results.move( op->r, op->stacktop ); } for ( ; ilast < function->ops.size(); ++ilast ) { yssa_opinst* sel = function->ops.at( ilast ); if ( sel->opcode == YSSA_IMPLICIT ) { continue; } if ( sel->opcode == YSSA_SELECT ) { assert( sel->operand_count == 1 ); assert( sel->operand[ 0 ] == op ); if ( sel->r != yl_opinst::NOVAL ) { results.move( sel->r, op->stacktop + sel->select ); } continue; } break; } results.emit( p, finalop->sloc ); return ilast - index; } case YL_ITER: case YL_ITERKEY: { unsigned a = operand( op, 0 ); p->ops.emplace_back( (yl_opcode)op->opcode, op->r, a, 0 ); p->slocs.push_back( op->sloc ); p->itercount = std::max( p->itercount, (size_t)op->r + 1 ); return 1; } case YL_NEXT1: { if ( op->r != yl_opinst::NOVAL ) { p->ops.emplace_back( YL_NEXT1, op->r, op->a ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_NEXT2: { // Find selects. unsigned r = yl_opinst::NOVAL; unsigned b = yl_opinst::NOVAL; size_t n; for ( n = 1; index + n < function->ops.size(); ++n ) { yssa_opinst* sel = function->ops.at( index + n ); if ( sel->opcode == YSSA_SELECT ) { assert( sel->operand_count == 1 ); assert( sel->operand[ 0 ] == op ); if ( sel->select == 0 ) { r = sel->r; } else if ( sel->select == 1 ) { b = sel->r; } else { assert( ! "invalid select index" ); } } else { break; } } assert( r != yl_opinst::NOVAL ); assert( b != yl_opinst::NOVAL ); p->ops.emplace_back( YL_NEXT2, r, op->a, b ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)r + 1 ); p->stackcount = std::max( p->stackcount, (size_t)b + 1 ); return n; } case YL_GETUP: { if ( op->r != yl_opinst::NOVAL ) { p->ops.emplace_back( YL_GETUP, op->r, op->a, 0 ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_SETUP: { p->ops.emplace_back( YL_SETUP, operand( op, 0 ), op->a, 0 ); p->slocs.push_back( op->sloc ); return 1; } case YL_OBJECT: { assert( op->result_count == 1 ); if ( op->r != yl_opinst::NOVAL ) { unsigned a = op->operand_count ? operand( op, 0 ) : yl_opinst::NOVAL; p->ops.emplace_back( (yl_opcode)op->opcode, op->r, a, 0 ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_CLOSE: { p->ops.emplace_back( YL_CLOSE, 0, op->a, op->b ); p->slocs.push_back( op->sloc ); return 1; } case YL_ARRAY: case YL_TABLE: { if ( op->r != yl_opinst::NOVAL ) { p->ops.emplace_back( (yl_opcode)op->opcode, op->r, op->c ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_KEY: { if ( op->r != yl_opinst::NOVAL ) { unsigned b = (unsigned)p->strvals.at( op->key ); p->ops.emplace_back( YL_KEY, op->r, operand( op, 0 ), b ); p->slocs.push_back( op->sloc ); p->ops.emplace_back( YL_ILCACHE, 0, (unsigned)( p->ilcount++ ) ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_SETKEY: { unsigned r = operand( op, 0 ); unsigned a = operand( op, 1 ); unsigned b = (unsigned)p->strvals.at( op->key ); p->ops.emplace_back( YL_SETKEY, r, a, b ); p->slocs.push_back( op->sloc ); p->ops.emplace_back( YL_ILCACHE, 0, (unsigned)( p->ilcount++ ) ); p->slocs.push_back( op->sloc ); return 1; } case YL_SETINKEY: case YL_SETINDEX: { assert( op->operand_count == 3 ); unsigned r = operand( op, 0 ); unsigned a = operand( op, 1 ); unsigned b = operand( op, 2 ); p->ops.emplace_back( (yl_opcode)op->opcode, r, a, b ); p->slocs.push_back( op->sloc ); return 1; } case YL_DELKEY: { unsigned a = operand( op, 0 ); unsigned b = (unsigned)p->strvals.at( op->key ); p->ops.emplace_back( YL_DELKEY, 0, a, b ); p->slocs.push_back( op->sloc ); return 1; } case YL_DELINKEY: { unsigned a = operand( op, 0 ); unsigned b = operand( op, 1 ); p->ops.emplace_back( YL_DELINKEY, 0, a, b ); p->slocs.push_back( op->sloc ); return 1; } case YL_APPEND: { unsigned a = operand( op, 0 ); unsigned r = operand( op, 1 ); p->ops.emplace_back( YL_APPEND, r, a, 0 ); p->slocs.push_back( op->sloc ); return 1; } case YL_THROW: { p->ops.emplace_back( YL_THROW, operand( op, 0 ), 0, 0 ); p->slocs.push_back( op->sloc ); return 1; } case YL_EXCEPT: { if ( op->r != yl_opinst::NOVAL ) { p->ops.emplace_back( YL_EXCEPT, op->r, 0, 0 ); p->slocs.push_back( op->sloc ); p->stackcount = std::max( p->stackcount, (size_t)op->r + 1 ); } return 1; } case YL_HANDLE: { p->ops.emplace_back( YL_HANDLE, 0, 0, 0 ); p->slocs.push_back( op->sloc ); return 1; } case YL_UNWIND: { p->ops.emplace_back( YL_UNWIND, 0, 0, 0 ); p->slocs.push_back( op->sloc ); return 1; } case YSSA_PARAM: { // Get all parameters into the correct registers. ygen_movgraph params; size_t n; for ( n = 0; index + n < function->ops.size(); ++n ) { yssa_opinst* param = function->ops.at( index + n ); if ( param->opcode == YSSA_PARAM ) { unsigned a = param->select + 1; p->stackcount = std::max( p->stackcount, (size_t)a + 1 ); if ( param->r != yl_opinst::NOVAL ) { params.move( param->r, a ); } } else { break; } } params.emit( p, op->sloc ); return n; } case YSSA_IMPLICIT: case YSSA_ITEREACH: case YSSA_PHI: case YSSA_VAR: { // Ignore these ops. return 1; } case YL_SWP: case YL_JMP: case YL_JMPT: case YL_JMPF: case YL_JMPV: case YL_JMPN: case YL_UPLOCAL: case YL_UPUPVAL: case YSSA_SELECT: case YSSA_REF: default: { assert( ! "unexpected SSA op" ); return 1; } } }
static dtStatus filterSmallRegions(dtTileCacheAlloc* alloc, dtTileCacheLayer& layer, int minRegionArea, int mergeRegionSize, unsigned short& maxRegionId, unsigned short* srcReg) { const int w = (int)layer.header->width; const int h = (int)layer.header->height; const int nreg = maxRegionId+1; dtFixedArray<dtLayerRegion> regions(alloc, nreg); if (!regions) { return DT_FAILURE | DT_OUT_OF_MEMORY; } // Construct regions regions.set(0); for (int i = 0; i < nreg; ++i) regions[i] = dtLayerRegion((unsigned short)i); // Find edge of a region and find connections around the contour. for (int y = 0; y < h; ++y) { const bool borderY = (y == 0) || (y == (h - 1)); for (int x = 0; x < w; ++x) { const int i = x+y*w; unsigned short r = srcReg[i]; if (r == DT_TILECACHE_NULL_AREA || r >= nreg) continue; dtLayerRegion& reg = regions[r]; reg.cellCount++; reg.border |= borderY || (x == 0) || (x == (w - 1)); // Have found contour if (reg.connections.size() > 0) continue; reg.areaType = layer.areas[i]; // Check if this cell is next to a border. int ndir = -1; for (int dir = 0; dir < 4; ++dir) { if (isSolidEdge(layer, srcReg, x, y, i, dir)) { ndir = dir; break; } } if (ndir != -1) { // The cell is at border. // Walk around the contour to find all the neighbours. walkContour(x, y, i, ndir, layer, srcReg, reg.connections); } } } // Remove too small regions. dtIntArray stack(32); dtIntArray trace(32); for (int i = 0; i < nreg; ++i) { dtLayerRegion& reg = regions[i]; if (reg.id == 0) continue; if (reg.cellCount == 0) continue; if (reg.visited) continue; // Count the total size of all the connected regions. // Also keep track of the regions connects to a tile border. bool connectsToBorder = false; int cellCount = 0; stack.resize(0); trace.resize(0); reg.visited = true; stack.push(i); while (stack.size()) { // Pop int ri = stack.pop(); dtLayerRegion& creg = regions[ri]; connectsToBorder |= creg.border; cellCount += creg.cellCount; trace.push(ri); for (int j = 0; j < creg.connections.size(); ++j) { dtLayerRegion& neireg = regions[creg.connections[j]]; if (neireg.visited) continue; if (neireg.id == 0) continue; // Visit stack.push(neireg.id); neireg.visited = true; } } // If the accumulated regions size is too small, remove it. // Do not remove areas which connect to tile borders // as their size cannot be estimated correctly and removing them // can potentially remove necessary areas. if (cellCount < minRegionArea && !connectsToBorder) { // Kill all visited regions. for (int j = 0; j < trace.size(); ++j) { regions[trace[j]].cellCount = 0; regions[trace[j]].id = 0; } } } // Merge too small regions to neighbour regions. int mergeCount = 0 ; do { mergeCount = 0; for (int i = 0; i < nreg; ++i) { dtLayerRegion& reg = regions[i]; if (reg.id == 0) continue; if (reg.cellCount == 0) continue; // Check to see if the region should be merged. if (reg.cellCount > mergeRegionSize && reg.border) continue; // Small region with more than 1 connection. // Or region which is not connected to a border at all. // Find smallest neighbour region that connects to this one. int smallest = 0xfffffff; unsigned short mergeId = reg.id; for (int j = 0; j < reg.connections.size(); ++j) { dtLayerRegion& mreg = regions[reg.connections[j]]; if (mreg.id == 0) continue; if (mreg.cellCount < smallest && canMergeWithRegion(reg, mreg) && canMergeWithRegion(mreg, reg)) { smallest = mreg.cellCount; mergeId = mreg.id; } } // Found new id. if (mergeId != reg.id) { unsigned short oldId = reg.id; dtLayerRegion& target = regions[mergeId]; // Merge neighbours. if (mergeRegions(target, reg)) { // Fixup regions pointing to current region. for (int j = 0; j < nreg; ++j) { if (regions[j].id == 0) continue; // If another region was already merged into current region // change the nid of the previous region too. if (regions[j].id == oldId) regions[j].id = mergeId; // Replace the current region with the new one if the // current regions is neighbour. replaceNeighbour(regions[j], oldId, mergeId); } mergeCount++; } } } } while (mergeCount > 0); // Compress region Ids. for (int i = 0; i < nreg; ++i) { regions[i].remap = false; if (regions[i].id == DT_TILECACHE_NULL_AREA) continue; // Skip nil regions. regions[i].remap = true; } unsigned short regIdGen = 0; for (int i = 0; i < nreg; ++i) { if (!regions[i].remap) continue; unsigned short oldId = regions[i].id; unsigned short newId = ++regIdGen; for (int j = i; j < nreg; ++j) { if (regions[j].id == oldId) { regions[j].id = newId; regions[j].remap = false; } } } maxRegionId = regIdGen; // Remap regions. for (int i = w*h-1; i >= 0; i--) { srcReg[i] = regions[srcReg[i]].id; } for (int i = 0; i < nreg; ++i) regions[i].~dtLayerRegion(); return DT_SUCCESS; }
static void MergeAndCompressRegions(dtTileCacheAlloc* alloc, dtTileCacheLayer& layer, dtLayerMonotoneRegion* regs, int nregs, const int minRegionArea, const int mergeRegionArea) { for (int i = 0; i < nregs; ++i) regs[i].regId = (unsigned short)(i + 1); // Remove too small regions. if (minRegionArea > 0) { dtIntArray stack(32); dtIntArray trace(32); for (int i = 0; i < nregs; ++i) { dtLayerMonotoneRegion& reg = regs[i]; if (reg.visited || reg.area == 0) continue; // Count the total size of all the connected regions. // Also keep track of the regions connects to a tile border. bool connectsToBorder = false; int cellCount = 0; stack.resize(0); trace.resize(0); reg.visited = true; stack.push(i); while (stack.size()) { // Pop int ri = stack.pop(); dtLayerMonotoneRegion& creg = regs[ri]; connectsToBorder |= creg.border; cellCount += creg.area; trace.push(ri); for (int j = 0; j < creg.neis.size(); ++j) { dtLayerMonotoneRegion& neireg = regs[creg.neis[j]]; if (neireg.visited) continue; if (neireg.regId == 0) continue; // Visit stack.push(neireg.regId - 1); neireg.visited = true; } } // If the accumulated regions size is too small, remove it. // Do not remove areas which connect to tile borders // as their size cannot be estimated correctly and removing them // can potentially remove necessary areas. if (cellCount < minRegionArea && !connectsToBorder) { // Kill all visited regions. for (int j = 0; j < trace.size(); ++j) { regs[trace[j]].area = 0; regs[trace[j]].regId = 0; } } } } for (int i = 0; i < nregs; ++i) { dtLayerMonotoneRegion& reg = regs[i]; if (reg.regId == 0) continue; // don't use mergeRegionArea, it doesn't work well with monotone partitioning // (results in even more long thin polys) int merge = -1; int mergea = 0; for (int j = 0; j < reg.neis.size(); ++j) { const unsigned short nei = (unsigned short)reg.neis[j]; dtLayerMonotoneRegion& regn = regs[nei]; if (reg.regId == regn.regId) continue; if (reg.areaId != regn.areaId || reg.chunkId != regn.chunkId) continue; if (regn.area > mergea) { if (canMerge(reg.regId, regn.regId, regs, nregs)) { mergea = regn.area; merge = (int)nei; } } } if (merge != -1) { const unsigned short oldId = reg.regId; const unsigned short newId = regs[merge].regId; for (int j = 0; j < nregs; ++j) if (regs[j].regId == oldId) regs[j].regId = newId; } } unsigned short regId = 0; if (nregs < 256) { // Compact ids. unsigned short remap[256]; memset(remap, 0, sizeof(unsigned short)*256); // Find number of unique regions. for (int i = 0; i < nregs; ++i) remap[regs[i].regId] = 1; // skip region id 0, it's used for skipping minRegionArea remap[0] = 0; for (int i = 1; i < 256; ++i) if (remap[i]) remap[i] = ++regId; // Remap ids. for (int i = 0; i < nregs; ++i) regs[i].regId = remap[regs[i].regId]; } else { for (int i = 0; i < nregs; ++i) regs[i].remap = true; for (int i = 0; i < nregs; ++i) { // skip region id 0, it's used for skipping minRegionArea if (!regs[i].remap || regs[i].regId == 0) continue; unsigned short oldId = regs[i].regId; unsigned short newId = ++regId; for (int j = i; j < nregs; ++j) { if (regs[j].regId == oldId) { regs[j].regId = newId; regs[j].remap = false; } } } } layer.regCount = regId; const int maxi = (int)layer.header->width * (int)layer.header->height; for (int i = 0; i < maxi; ++i) { if (layer.regs[i] != 0xffff) layer.regs[i] = regs[layer.regs[i]].regId; } alloc->free(regs); }
boost::shared_ptr<StackFrame> JavaVM::createStack() { boost::shared_ptr<StackFrame> stack(new StackFrame()); return stack; }
//------------------------------------------------------------------------------ //! void BIH::create( const Vector<AABBoxf*>& bboxes, const Vector<Vec3f>& centers, Vector<uint>* ids, uint leafSize, uint maxDepth ) { CHECK( bboxes.size() == centers.size() ); DBG_BLOCK( os_bih, "Start computing BIH..." ); DBG( Timer timer ); // Initialization. DBG_MSG( os_bih, "# of elements: " << bboxes.size() << " " << centers.size() << "\n" ); // 1. Init maximum recursion level. if( maxDepth == 0 ) { maxDepth = (int)CGM::log2( float(centers.size()) ) * 2 + 1; } _maxDepth = CGM::min( maxDepth, (uint)100 ); // 2. Init ids. if( ids == 0 ) { _ids.resize( centers.size() ); for( uint i = 0; i < _ids.size(); ++i ) { _ids[i] = i; } } else { _ids.swap( *ids ); } Vector<uint> remap( centers.size() ); for( uint i = 0; i < remap.size(); ++i ) { remap[i] = i; } // 3. Init nodes and root. //_nodes.reserve(); _nodes.resize(1); // 4. Compute bounding box. AABBoxf nodeBox = AABBoxf::empty(); for( uint i = 0; i < bboxes.size(); ++i ) { nodeBox |= *bboxes[i]; } AABBoxf splitBox = nodeBox; // 5. Stack. Vector<BuildStackNode> stack( maxDepth ); uint stackID = 0; uint maxPrim = 0; uint maxD = 0; // Construct BIH. uint begin = 0; uint end = uint(_ids.size()); uint depth = 1; uint node = 0; while( 1 ) { // Do we have a root node? if( (end - begin <= leafSize) || depth >= maxDepth ) { // Root node. _nodes[node]._index = (begin << 3) + 3; _nodes[node]._numElements = end-begin; maxPrim = CGM::max( maxPrim, end-begin ); maxD = CGM::max( maxD, depth ); // Are we done? if( stackID == 0 ) { break; } stack[--stackID].get( node, begin, end, depth, nodeBox, splitBox ); } else { // Compute split plane and axis. uint axis = splitBox.longestSide(); float splitPlane = splitBox.center( axis ); // Partition primitives. AABBoxf leftNodeBox = AABBoxf::empty(); AABBoxf rightNodeBox = AABBoxf::empty(); uint pivot = begin; for( uint i = begin; i < end; ++i ) { if( centers[remap[i]](axis) < splitPlane ) { leftNodeBox |= (*bboxes[remap[i]]); CGM::swap( remap[i], remap[pivot] ); CGM::swap( _ids[i], _ids[pivot++] ); } else { rightNodeBox |= (*bboxes[remap[i]]); } } // Construct node. ++depth; // No left node. if( pivot == begin ) { uint childNode = uint(_nodes.size()); // Current node. _nodes[node]._index = (childNode << 3) + 4 + axis; _nodes[node]._plane[0] = rightNodeBox.min( axis ); _nodes[node]._plane[1] = rightNodeBox.max( axis ); // Create nodes. _nodes.pushBack( Node() ); // Child node. node = childNode; nodeBox = rightNodeBox; splitBox.slab( axis )(0) = CGM::max( splitPlane, rightNodeBox.min( axis ) ); } // No right node. else if( pivot == end ) { uint childNode = uint(_nodes.size()); // Current node. _nodes[node]._index = (childNode << 3) + 4 + axis; _nodes[node]._plane[0] = leftNodeBox.min( axis ); _nodes[node]._plane[1] = leftNodeBox.max( axis ); // Create nodes. _nodes.pushBack( Node() ); // Child node. node = childNode; nodeBox = leftNodeBox; splitBox.slab( axis )(1) = CGM::min( splitPlane, leftNodeBox.max( axis ) ); } // Left and right node. else { uint leftNode = uint(_nodes.size()); // Current node. _nodes[node]._index = (leftNode << 3) + axis; _nodes[node]._plane[0] = leftNodeBox.max( axis ); _nodes[node]._plane[1] = rightNodeBox.min( axis ); // Create nodes. _nodes.pushBack( Node() ); _nodes.pushBack( Node() ); // Right node. AABBoxf rsplitBox( splitBox ); rsplitBox.slab( axis )(0) = splitPlane; stack[stackID++].set( leftNode+1, pivot, end, depth, rightNodeBox, rsplitBox ); // Left node. node = leftNode; end = pivot; nodeBox = leftNodeBox; splitBox.slab( axis )(1) = splitPlane; } } } DBG( double time = timer.elapsed() ); DBG_MSG( os_bih, "...finish in " << time << " sec." ); DBG_MSG( os_bih, "# of nodes: " << _nodes.size() ); DBG_MSG( os_bih, "# of indices: " << _ids.size() ); DBG_MSG( os_bih, "max primitives in a leaf: " << maxPrim ); DBG_MSG( os_bih, "max depth: " << maxD << " " << maxDepth ); }
void LaplacianFilter::parse(vector<string> args) { assert(args.size() == 0, "-laplacianpyramid does not take arguments.\n"); push(apply(stack(0), 0.f, 0.f, 0.f)); }
//------------------------------------------------------------------------------ //! bool BIH::trace( const Rayf& ray, Hit& hit, IntersectFunc intersect, void* data ) const { DBG_BLOCK( os_bih_trace, "BIH::trace(" << ray.origin() << ray.direction() << " hit: t=" << hit._t << " id=" << hit._id << ")" ); if( _nodes.empty() ) { return false; } Vec3f invDir = ray.direction().getInversed(); // Compute traversal order. uint order[3]; order[0] = invDir(0) >= 0.0f ? 0 : 1; order[1] = invDir(1) >= 0.0f ? 0 : 1; order[2] = invDir(2) >= 0.0f ? 0 : 1; float tmin = 0.0f; float tmax = hit._t; bool impact = false; // Traverse tree. Vector<TraversalStackNode> stack( _maxDepth ); uint stackID = 0; const Node* node = &_nodes[0]; while( 1 ) { DBG_MSG( os_bih_trace, "Visiting " << *node ); if( node->isInteriorNode() ) { uint axis = node->axis(); float tplane0 = ( node->_plane[order[axis]] - ray.origin()(axis)) * invDir(axis); float tplane1 = ( node->_plane[1-order[axis]] - ray.origin()(axis)) * invDir(axis); // Clip node. if( node->isClipNode() ) { // FIXME: we could probably do better (not traversing this node). node = &_nodes[node->index()]; tmin = CGM::max( tmin, tplane0 ); tmax = CGM::min( tmax, tplane1 ); continue; } bool traverse0 = tmin < tplane0; bool traverse1 = tmax > tplane1; if( traverse0 ) { if( traverse1 ) { stack[stackID++].set( &_nodes[node->index() + 1-order[axis]], CGM::max( tmin, tplane1 ), tmax ); } node = &_nodes[node->index() + order[axis]]; tmax = CGM::min( tmax, tplane0 ); } else { if( traverse1 ) { node = &_nodes[node->index() + 1-order[axis]]; tmin = CGM::max( tmin, tplane1 ); } else { // Unstack. do { if( stackID == 0 ) { return impact; } stack[--stackID].get( node, tmin, tmax ); tmax = CGM::min( tmax, hit._t ); } while( tmin > tmax ); } } } else { // We are in a leaf node. // Intersects all primitives in it. uint numElems = node->_numElements; uint id = node->index(); for( uint i = 0; i < numElems; ++i, ++id ) { if( intersect( ray, _ids[id], hit._t, data ) ) { impact = true; hit._id = _ids[id]; } } // Unstack. do { if( stackID == 0 ) { return impact; } stack[--stackID].get( node, tmin, tmax ); tmax = CGM::min( tmax, hit._t ); } while( tmin > tmax ); } } }
void AutoJSAPI::ReportException() { if (!HasException()) { return; } // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null // compartment when the destructor is called. However, the JS engine // requires us to be in a compartment when we fetch the pending exception. // In this case, we enter the privileged junk scope and don't dispatch any // error events. JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx())); if (!errorGlobal) { if (mIsMainThread) { errorGlobal = xpc::PrivilegedJunkScope(); } else { errorGlobal = workers::GetCurrentThreadWorkerGlobal(); } } JSAutoCompartment ac(cx(), errorGlobal); JS::Rooted<JS::Value> exn(cx()); js::ErrorReport jsReport(cx()); if (StealException(&exn) && jsReport.init(cx(), exn, js::ErrorReport::WithSideEffects)) { if (mIsMainThread) { RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport(); RefPtr<nsGlobalWindow> win = xpc::WindowGlobalOrNull(errorGlobal); if (!win) { // We run addons in a separate privileged compartment, but they still // expect to trigger the onerror handler of their associated DOM Window. win = xpc::AddonWindowOrNull(errorGlobal); } nsPIDOMWindowInner* inner = win ? win->AsInner() : nullptr; xpcReport->Init(jsReport.report(), jsReport.message(), nsContentUtils::IsCallerChrome(), inner ? inner->WindowID() : 0); if (inner && jsReport.report()->errorNumber != JSMSG_OUT_OF_MEMORY) { DispatchScriptErrorEvent(inner, JS_GetRuntime(cx()), xpcReport, exn); } else { JS::Rooted<JSObject*> stack(cx(), xpc::FindExceptionStackForConsoleReport(inner, exn)); xpcReport->LogToConsoleWithStack(stack); } } else { // On a worker, we just use the worker error reporting mechanism and don't // bother with xpc::ErrorReport. This will ensure that all the right // events (which are a lot more complicated than in the window case) get // fired. workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(worker); MOZ_ASSERT(worker->GetJSContext() == cx()); // Before invoking ReportError, put the exception back on the context, // because it may want to put it in its error events and has no other way // to get hold of it. After we invoke ReportError, clear the exception on // cx(), just in case ReportError didn't. JS_SetPendingException(cx(), exn); worker->ReportError(cx(), jsReport.message(), jsReport.report()); ClearException(); } } else { NS_WARNING("OOMed while acquiring uncaught exception from JSAPI"); ClearException(); } }
// -------------------------------------------------------------------------- // void Test000( void ) { // ========================================================================== // // void Test000( // // void) // // // // LIFO stack demo. // // ========================================================================== // // INPUT // // ========================================================================== // // - none // // ========================================================================== // // OUTPUT // // ========================================================================== // // - none // // ========================================================================== // // ========================================================================== // // VARIABLES DECLARATION // // ========================================================================== // // Local variables int N = 10; bitpit::LIFOStack<ivector1D> stack(5); // Counters int i; // ========================================================================== // // OPENING MESSAGE // // ========================================================================== // { // Scope variables ------------------------------------------------------ // // none // Output message ------------------------------------------------------- // cout << "================== TEST 000: LIFO stack demo ==================" << endl; } // ========================================================================== // // INSERT ELEMENTS INTO THE LIFO STACK // // ========================================================================== // { // Scope variables ------------------------------------------------------ // ivector1D dummy(2, 0); // PUSH elements into the LIFO stack ------------------------------------ // for (i = 0; i < N; i++) { dummy[0] = i+1; dummy[1] = -dummy[0]; cout << " * pushing element: " << dummy << endl; stack.push(dummy); stack.display(cout); } //next i // POP elements from the LIFO stack ------------------------------------- // for (i = 0; i < N; i++) { dummy = stack.pop(); cout << " * popped element: " << dummy << endl; stack.display(cout); } //next i } // ========================================================================== // // CLOSING MESSAGE // // ========================================================================== // { // Scope variables ------------------------------------------------------ // // none // Output message ------------------------------------------------------- // cout << "====================== TEST 000: done!! =======================" << endl; } return; };
address Thread::stack_base() const { const ExecutionStack::Raw stack(execution_stack()); return (address)stack().field_base( JavaStackDirection < 0 ? stack().length() : 0 ); }
static int vector3_cross(lua_State* L) { LuaStack stack(L); stack.push_vector3(cross(stack.get_vector3(1), stack.get_vector3(2))); return 1; }
ItemStack operator+(ItemStack const &is, sf::Uint32 const &toAdd) { ItemStack stack(is); return stack += toAdd; }
static int vector3_new(lua_State* L) { LuaStack stack(L); stack.push_vector3(vector3(stack.get_float(1), stack.get_float(2), stack.get_float(3))); return 1; }
ItemStack operator-(ItemStack const &is, sf::Uint32 const &toRemove) { ItemStack stack(is); return stack -= toRemove; }
static int vector3_set_length(lua_State* L) { LuaStack stack(L); set_length(stack.get_vector3(1), stack.get_float(2)); return 0; }
int main() { char ip[20],r[20],st,an; int ir,ic,j=0,k; char t[5][6][10]={"$","$","TH","$","TH","$", "+TH","$","e","e","$","e", "$","$","FU","$","FU","$", "e","*FU","e","e","$","e", "$","$","(E)","$","i","$"}; clrscr(); printf("\nEnter any String(Append with $)"); gets(ip); printf("Stack\tInput\tOutput\n\n"); push("$E"); display(); printf("\t%s\n",ip); for(j=0;ip[j]!='\0';) { if(TOS()==an) { pop(); display(); display1(ip,j+1); printf("\tPOP\n"); j++; } an=ip[j]; st=TOS(); if(st=='E')ir=0; else if(st=='H')ir=1; else if(st=='T')ir=2; else if(st=='U')ir=3; else if(st=='F')ir=4; else { error(); break; } if(an=='+')ic=0; else if(an=='*')ic=1; else if(an=='(')ic=2; else if(an==')')ic=3; else if((an>='a'&&an<='z')||(an>='A'&&an<='Z')){ic=4;an='i';} else if(an=='$')ic=5; strcpy(r,strrev(t[ir][ic])); strrev(t[ir][ic]); pop(); push(r); if(TOS()=='e') { pop(); display(); display1(ip,j); printf("\t%c->%c\n",st,238); } else{ display(); display1(ip,j); printf("\t%c->%s\n",st,t[ir][ic]); } if(TOS()=='$'&&an=='$') break; if(TOS()=='$'){ error(); break; } } k=strcmp(stack(),"$"); if(k==0 && i==strlen(ip)) printf("\n Given String is accepted"); else printf("\n Given String is not accepted"); return 0; }
static int vector3_angle(lua_State* L) { LuaStack stack(L); stack.push_float(angle(stack.get_vector3(1), stack.get_vector3(2))); return 1; }
void grab_pointer(pointer_action_t pac) { PRINTF("grab pointer %u\n", pac); xcb_window_t win = XCB_NONE; xcb_point_t pos; query_pointer(&win, &pos); coordinates_t loc; if (locate_window(win, &loc)) { client_t *c = NULL; frozen_pointer->position = pos; frozen_pointer->action = pac; c = loc.node->client; frozen_pointer->monitor = loc.monitor; frozen_pointer->desktop = loc.desktop; frozen_pointer->node = loc.node; frozen_pointer->client = c; frozen_pointer->window = c->window; frozen_pointer->horizontal_fence = NULL; frozen_pointer->vertical_fence = NULL; switch (pac) { case ACTION_FOCUS: if (loc.node != mon->desk->focus) { bool backup = pointer_follows_monitor; pointer_follows_monitor = false; focus_node(loc.monitor, loc.desktop, loc.node); pointer_follows_monitor = backup; } else if (focus_follows_pointer) { stack(loc.node, true); } frozen_pointer->action = ACTION_NONE; break; case ACTION_MOVE: case ACTION_RESIZE_SIDE: case ACTION_RESIZE_CORNER: if (IS_FLOATING(c)) { frozen_pointer->rectangle = c->floating_rectangle; frozen_pointer->is_tiled = false; } else if (IS_TILED(c)) { frozen_pointer->rectangle = c->tiled_rectangle; frozen_pointer->is_tiled = (pac == ACTION_MOVE || c->state == STATE_PSEUDO_TILED); } else { frozen_pointer->action = ACTION_NONE; return; } if (pac == ACTION_RESIZE_SIDE) { float W = frozen_pointer->rectangle.width; float H = frozen_pointer->rectangle.height; float ratio = W / H; float x = pos.x - frozen_pointer->rectangle.x; float y = pos.y - frozen_pointer->rectangle.y; float diag_a = ratio * y; float diag_b = W - diag_a; if (x < diag_a) { if (x < diag_b) frozen_pointer->side = SIDE_LEFT; else frozen_pointer->side = SIDE_BOTTOM; } else { if (x < diag_b) frozen_pointer->side = SIDE_TOP; else frozen_pointer->side = SIDE_RIGHT; } } else if (pac == ACTION_RESIZE_CORNER) { int16_t mid_x = frozen_pointer->rectangle.x + (frozen_pointer->rectangle.width / 2); int16_t mid_y = frozen_pointer->rectangle.y + (frozen_pointer->rectangle.height / 2); if (pos.x > mid_x) { if (pos.y > mid_y) frozen_pointer->corner = CORNER_BOTTOM_RIGHT; else frozen_pointer->corner = CORNER_TOP_RIGHT; } else { if (pos.y > mid_y) frozen_pointer->corner = CORNER_BOTTOM_LEFT; else frozen_pointer->corner = CORNER_TOP_LEFT; } } if (frozen_pointer->is_tiled) { if (pac == ACTION_RESIZE_SIDE) { switch (frozen_pointer->side) { case SIDE_TOP: frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP); break; case SIDE_RIGHT: frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT); break; case SIDE_BOTTOM: frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN); break; case SIDE_LEFT: frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT); break; } } else if (pac == ACTION_RESIZE_CORNER) { switch (frozen_pointer->corner) { case CORNER_TOP_LEFT: frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP); frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT); break; case CORNER_TOP_RIGHT: frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_UP); frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT); break; case CORNER_BOTTOM_RIGHT: frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN); frozen_pointer->vertical_fence = find_fence(loc.node, DIR_RIGHT); break; case CORNER_BOTTOM_LEFT: frozen_pointer->horizontal_fence = find_fence(loc.node, DIR_DOWN); frozen_pointer->vertical_fence = find_fence(loc.node, DIR_LEFT); break; } } if (frozen_pointer->horizontal_fence != NULL) frozen_pointer->horizontal_ratio = frozen_pointer->horizontal_fence->split_ratio; if (frozen_pointer->vertical_fence != NULL) frozen_pointer->vertical_ratio = frozen_pointer->vertical_fence->split_ratio; } break; case ACTION_NONE: break; } } else { if (pac == ACTION_FOCUS) { monitor_t *m = monitor_from_point(pos); if (m != NULL && m != mon) focus_node(m, m->desk, m->desk->focus); } frozen_pointer->action = ACTION_NONE; } }
static int vector3_backward(lua_State* L) { LuaStack stack(L); stack.push_vector3(VECTOR3_BACKWARD); return 1; }
GlyphToType3::GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded /* = false */) { BYTE *glyph; tt_flags = NULL; xcoor = NULL; ycoor = NULL; epts_ctr = NULL; stack_depth = 0; pdf_mode = font->target_type < 0; /* Get a pointer to the data. */ glyph = find_glyph_data( font, charindex ); /* If the character is blank, it has no bounding box, */ /* otherwise read the bounding box. */ if ( glyph == (BYTE*)NULL ) { llx=lly=urx=ury=0; /* A blank char has an all zero BoundingBox */ num_ctr=0; /* Set this for later if()s */ } else { /* Read the number of contours. */ num_ctr = getSHORT(glyph); /* Read PostScript bounding box. */ llx = getFWord(glyph + 2); lly = getFWord(glyph + 4); urx = getFWord(glyph + 6); ury = getFWord(glyph + 8); /* Advance the pointer. */ glyph += 10; } /* If it is a simple character, load its data. */ if (num_ctr > 0) { load_char(font, glyph); } else { num_pts=0; } /* Consult the horizontal metrics table to determine */ /* the character width. */ if ( charindex < font->numberOfHMetrics ) { advance_width = getuFWord( font->hmtx_table + (charindex * 4) ); } else { advance_width = getuFWord( font->hmtx_table + ((font->numberOfHMetrics-1) * 4) ); } /* Execute setcachedevice in order to inform the font machinery */ /* of the character bounding box and advance width. */ stack(stream, 7); if (pdf_mode) { if (!embedded) { stream.printf("%d 0 %d %d %d %d d1\n", topost(advance_width), topost(llx), topost(lly), topost(urx), topost(ury) ); } } else if (font->target_type == PS_TYPE_42_3_HYBRID) { stream.printf("pop gsave .001 .001 scale %d 0 %d %d %d %d setcachedevice\n", topost(advance_width), topost(llx), topost(lly), topost(urx), topost(ury) ); } else { stream.printf("%d 0 %d %d %d %d _sc\n", topost(advance_width), topost(llx), topost(lly), topost(urx), topost(ury) ); } /* If it is a simple glyph, convert it, */ /* otherwise, close the stack business. */ if ( num_ctr > 0 ) /* simple */ { PSConvert(stream); } else if ( num_ctr < 0 ) /* composite */ { do_composite(stream, font, glyph); } if (font->target_type == PS_TYPE_42_3_HYBRID) { stream.printf("\ngrestore\n"); } stack_end(stream); }