static JSBool GrowTokenBuf(JSContext *cx, JSTokenBuf *tb) { jschar *base; ptrdiff_t offset, length; size_t tbsize; JSArenaPool *pool; base = tb->base; offset = PTRDIFF(tb->ptr, base, jschar); pool = &cx->tempPool; if (!base) { tbsize = TBMIN * sizeof(jschar); length = TBMIN; JS_ARENA_ALLOCATE_CAST(base, jschar *, pool, tbsize); } else { length = PTRDIFF(tb->limit, base, jschar); tbsize = length * sizeof(jschar); length <<= 1; JS_ARENA_GROW_CAST(base, jschar *, pool, tbsize, tbsize); } if (!base) { JS_ReportOutOfMemory(cx); return JS_FALSE; } tb->base = base; tb->limit = base + length; tb->ptr = base + offset; return JS_TRUE; }
/* * Passed in file system name is as listed in mnttab in the * mnt_special field. Replace any slashes with "__". */ static int dbdir_from_fsname(char *fsname, char *buf, size_t buflen) { char tmpbuf[MAXPATHLEN+1]; char *ptr; char *fsp; size_t i; if ((fsname == NULL) || (buf == NULL)) { return (-1); } strlcpy(tmpbuf, fsname, sizeof (tmpbuf)); fsp = tmpbuf; while ((ptr = strchr(fsp, '/')) != NULL) { strlcat(buf, "__", buflen); i = PTRDIFF(ptr, fsp); *ptr = '\0'; if (i > 0) { strlcat(buf, fsp, buflen); } fsp += (i + 1); } if (fsp != NULL) { strlcat(buf, fsp, buflen); } return (0); }
int next_imps(unsigned short *impbuf, int buflen, long timelen) { static int toput; static int bitrem; static dbyte dirpulse; unsigned short *impbufend, *impbufstart; impbufstart = impbuf; impbufend = impbuf + buflen; while(impbuf < impbufend - 1 && timelen > 0) { switch(playstate) { case PL_PAUSE: if(currlev && lead_pause) { PULSE(IMP_1MS); lead_pause --; } else if(lead_pause > 10) { if(tapeopt.blanknoise && !(rb->rand() % 64)) DPULSE(IMP_1MS * 10 - 1000, 1000); else DPULSE(IMP_1MS * 10, 0); lead_pause -= 10; } else if(lead_pause) { DPULSE(IMP_1MS, 0); lead_pause --; } else { if(tf_cseg.num || tf_cseg.sync1p || tf_cseg.sync2p || tf_cseg.ptr != tf_cseg.len) finished = 0; switch (tf_cseg.type) { case ST_NORM: playstate = PL_LEADER; break; case ST_DIRE: playstate = PL_DIRE; dirpulse = 0; break; case ST_PSEQ: playstate = PL_PSEQ; break; default: playstate = PL_NONE; } } break; case PL_LEADER: if(tf_cseg.num >= 2) { DPULSE(tf_cseg.pulse, tf_cseg.pulse); tf_cseg.num -= 2; } else if(tf_cseg.num) { PULSE(tf_cseg.pulse); tf_cseg.num --; } else { /* PL_SYNC */ if(tf_cseg.sync1p || tf_cseg.sync2p) DPULSE(tf_cseg.sync1p, tf_cseg.sync2p); bitrem = 0; playstate = PL_DATA; } break; case PL_DATA: if(!bitrem) { toput = next_data(); if(toput < 0) { playstate = PL_END; break; } if(tf_cseg.ptr != tf_cseg.len) { if(timelen > 16 * max(tf_cseg.onep, tf_cseg.zerop) && impbuf <= impbufend - 16) { int p1, p2, br, tp; p1 = tf_cseg.onep; p2 = tf_cseg.zerop; br = 8; tp = toput; while(br) { if(tp & 0x80) DPULSE(p1, p1); else DPULSE(p2, p2); br--; tp <<= 1; } bitrem = 0; break; } bitrem = 8; } else { bitrem = tf_cseg.bused; if(!bitrem) break; } } if(toput & 0x80) DPULSE(tf_cseg.onep, tf_cseg.onep); else DPULSE(tf_cseg.zerop, tf_cseg.zerop); bitrem--, toput <<= 1; break; case PL_PSEQ: { int b1, b2; dbyte pulse1, pulse2; b1 = next_data(); b2 = next_data(); if(b1 < 0 || b2 < 0) { playstate = PL_END; break; } pulse1 = b1 + (b2 << 8); b1 = next_data(); b2 = next_data(); if(b1 < 0 || b2 < 0) { PULSE(pulse1); playstate = PL_END; break; } pulse2 = b1 + (b2 << 8); DPULSE(pulse1, pulse2); } break; case PL_DIRE: for(;;) { if(!bitrem) { toput = next_data(); if(toput < 0) { playstate = PL_END; DPULSE(dirpulse, 0); break; } if(tf_cseg.ptr != tf_cseg.len) bitrem = 8; else { bitrem = tf_cseg.bused; if(!bitrem) break; } } bitrem--; toput <<= 1; if(((toput & 0x0100) ^ (currlev ? 0x0100 : 0x00))) { PULSE(dirpulse); dirpulse = tf_cseg.pulse; break; } dirpulse += tf_cseg.pulse; if(dirpulse >= 0x8000) { DPULSE(dirpulse, 0); dirpulse = 0; break; } } break; case PL_END: if(tf_cseg.pause) { PULSE(IMP_1MS); tf_cseg.pause--; if(currlev) PULSE(0); finished = 1; } playstate = PL_NONE; break; case PL_NONE: default: return PTRDIFF(impbuf, impbufstart); } } return PTRDIFF(impbuf, impbufstart); }
static int internal_coalesce(void) { BlockP block; BlockP previous; BlockP tail; #ifndef BLOCKS_GUARDED BlockP bin_copy[NBINS+2]; #endif size_t size; /* where size is used to specify an element of an array it should really be * called index, but to generate better code I got rid of the index variable */ F0("!!internal_coalesce..."); #ifdef STATS statsP->stats.coalesces++; #endif lookInBins = FALSE; totalFree = 0; /* set bins and overflow lists to empty */ for (size = 0; size <= NBINS+1; size++) { bin[size] = NULL; #ifndef BLOCKS_GUARDED bin_copy[size] = NULL; #endif } block = heapLow; /* NULL indicates previous doesn't point to start of free block */ previous = NULL; tail = NULL; while (block <= heapHigh) { if (INVALID(block)) return CORRUPT; if (FREE(block)) { /* free block */ if (previous == NULL) previous = block; } else if (previous != NULL) { size = PTRDIFF(block, previous) - OVERHEAD; /* set flags to Free */ totalFree += size; previous->size = (size | FREEBIT); if (size <= MAXBINSIZE) { /* return to bin */ size /= BINRANGE; if (bin[size] == NULL) bin[size] = previous; else { /* if not BLOCKS_GUARDED use guard word of first block in bin to hold * a pointer to the last block in the list for this bin otherwise * use the bin_copy array. This allows me to keep the list in * ascending address order. Remember to put back the guard words at * the end of coalescing if BLOCKS_GUARDED. */ #ifdef BLOCKS_GUARDED ((BlockP) bin[size]->guard)->next = previous; #else (bin_copy[size])->next = previous; #endif } #ifdef BLOCKS_GUARDED bin[size]->guard = (int) previous; #else bin_copy[size] = previous; #endif } else { /* put block on overflow list */ if (bin[0] == NULL) {bin[0] = previous; previous->previous = NULL;} else {tail->next = previous; previous->previous = tail;} tail = previous; } previous = NULL; } ADDBYTESTO(block, SIZE(block) + OVERHEAD); } /* replace the guard words at the start of the bins lists */ for (size = 1; size <= NBINS; size++) { if (bin[size] != NULL) { lookInBins = TRUE; #ifdef BLOCKS_GUARDED ((BlockP) bin[size]->guard)->next = NULL; bin[size]->guard = GUARDCONSTANT; #else (bin_copy[size])->next = NULL; #endif } } /* do both ends of overflow list */ if (bin[0] != NULL) { tail->next = NULL; bin[NBINS+1] = tail; } else { bin[NBINS+1] = NULL; } lastFreeBlockOnHeap = bin[NBINS+1]; F0(" ... complete\n"); return OK; }
static int32 GetChar(JSTokenStream *ts) { int32 c; ptrdiff_t i, j, len, olen; JSBool crflag; char cbuf[JS_LINE_LIMIT]; jschar *ubuf, *nl; if (ts->ungetpos != 0) { c = ts->ungetbuf[--ts->ungetpos]; } else { do { if (ts->linebuf.ptr == ts->linebuf.limit) { len = PTRDIFF(ts->userbuf.limit, ts->userbuf.ptr, jschar); if (len <= 0) { if (!ts->file) { ts->flags |= TSF_EOF; return EOF; } /* Fill ts->userbuf so that \r and \r\n convert to \n. */ crflag = (ts->flags & TSF_CRFLAG) != 0; len = my_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file); if (len <= 0) { ts->flags |= TSF_EOF; return EOF; } olen = len; ubuf = ts->userbuf.base; i = 0; if (crflag) { ts->flags &= ~TSF_CRFLAG; if (cbuf[0] != '\n') { ubuf[i++] = '\n'; len++; ts->linepos--; } } for (j = 0; i < len; i++, j++) ubuf[i] = (jschar) (unsigned char) cbuf[j]; ts->userbuf.limit = ubuf + len; ts->userbuf.ptr = ubuf; } if (ts->listener) { ts->listener(ts->filename, ts->lineno, ts->userbuf.ptr, len, &ts->listenerTSData, ts->listenerData); } /* * Any one of \n, \r, or \r\n ends a line (longest match wins). * Also allow the Unicode line and paragraph separators. */ for (nl = ts->userbuf.ptr; nl < ts->userbuf.limit; nl++) { /* * Try to prevent value-testing on most characters by * filtering out characters that aren't 000x or 202x. */ if ((*nl & 0xDFD0) == 0) { if (*nl == '\n') break; if (*nl == '\r') { if (nl + 1 < ts->userbuf.limit && nl[1] == '\n') nl++; break; } if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) break; } } /* * If there was a line terminator, copy thru it into linebuf. * Else copy JS_LINE_LIMIT-1 bytes into linebuf. */ if (nl < ts->userbuf.limit) len = PTRDIFF(nl, ts->userbuf.ptr, jschar) + 1; if (len >= JS_LINE_LIMIT) len = JS_LINE_LIMIT - 1; js_strncpy(ts->linebuf.base, ts->userbuf.ptr, len); ts->userbuf.ptr += len; olen = len; /* * Make sure linebuf contains \n for EOL (don't do this in * userbuf because the user's string might be readonly). */ if (nl < ts->userbuf.limit) { if (*nl == '\r') { if (ts->linebuf.base[len-1] == '\r') { /* * Does the line segment end in \r? We must check * for a \n at the front of the next segment before * storing a \n into linebuf. This case matters * only when we're reading from a file. */ if (nl + 1 == ts->userbuf.limit && ts->file) { len--; ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */ if (len == 0) { /* * This can happen when a segment ends in * \r\r. Start over. ptr == limit in this * case, so we'll fall into buffer-filling * code. */ return GetChar(ts); } } else { ts->linebuf.base[len-1] = '\n'; } } } else if (*nl == '\n') { if (nl > ts->userbuf.base && nl[-1] == '\r' && ts->linebuf.base[len-2] == '\r') { len--; JS_ASSERT(ts->linebuf.base[len] == '\n'); ts->linebuf.base[len-1] = '\n'; } } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) { ts->linebuf.base[len-1] = '\n'; } } /* Reset linebuf based on adjusted segment length. */ ts->linebuf.limit = ts->linebuf.base + len; ts->linebuf.ptr = ts->linebuf.base; /* Update position of linebuf within physical userbuf line. */ if (!(ts->flags & TSF_NLFLAG)) ts->linepos += ts->linelen; else ts->linepos = 0; if (ts->linebuf.limit[-1] == '\n') ts->flags |= TSF_NLFLAG; else ts->flags &= ~TSF_NLFLAG; /* Update linelen from original segment length. */ ts->linelen = olen; } c = *ts->linebuf.ptr++; } while (JS_ISFORMAT(c)); } if (c == '\n') ts->lineno++; return c; }