📄 js.c
字号:
case 'S': if (++i == argc) return usage(); /* Set maximum stack size. */ gMaxStackSize = atoi(argv[i]); break; case 'z': obj = split_setup(cx); break; default: return usage(); } } if (filename || isInteractive) Process(cx, obj, filename, forceTTY); return gExitCode;}static JSBoolVersion(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ if (argc > 0 && JSVAL_IS_INT(argv[0])) *rval = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) JSVAL_TO_INT(argv[0]))); else *rval = INT_TO_JSVAL(JS_GetVersion(cx)); return JS_TRUE;}static struct { const char *name; uint32 flag;} js_options[] = { {"strict", JSOPTION_STRICT}, {"werror", JSOPTION_WERROR}, {"atline", JSOPTION_ATLINE}, {"xml", JSOPTION_XML}, {0, 0}};static JSBoolOptions(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ uint32 optset, flag; uintN i, j, found; JSString *str; const char *opt; char *names; optset = 0; for (i = 0; i < argc; i++) { str = JS_ValueToString(cx, argv[i]); if (!str) return JS_FALSE; opt = JS_GetStringBytes(str); for (j = 0; js_options[j].name; j++) { if (strcmp(js_options[j].name, opt) == 0) { optset |= js_options[j].flag; break; } } } optset = JS_ToggleOptions(cx, optset); names = NULL; found = 0; while (optset != 0) { flag = optset; optset &= optset - 1; flag &= ~optset; for (j = 0; js_options[j].name; j++) { if (js_options[j].flag == flag) { names = JS_sprintf_append(names, "%s%s", names ? "," : "", js_options[j].name); found++; break; } } } if (!found) names = strdup(""); if (!names) { JS_ReportOutOfMemory(cx); return JS_FALSE; } str = JS_NewString(cx, names, strlen(names)); if (!str) { free(names); return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE;}static JSBoolLoad(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ uintN i; JSString *str; const char *filename; JSScript *script; JSBool ok; jsval result; uint32 oldopts; for (i = 0; i < argc; i++) { str = JS_ValueToString(cx, argv[i]); if (!str) return JS_FALSE; argv[i] = STRING_TO_JSVAL(str); filename = JS_GetStringBytes(str); errno = 0; oldopts = JS_GetOptions(cx); JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO); script = JS_CompileFile(cx, obj, filename); if (!script) { ok = JS_FALSE; } else { ok = !compileOnly ? JS_ExecuteScript(cx, obj, script, &result) : JS_TRUE; JS_DestroyScript(cx, script); } JS_SetOptions(cx, oldopts); if (!ok) return JS_FALSE; } return JS_TRUE;}/* * function readline() * Provides a hook for scripts to read a line from stdin. */static JSBoolReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){#define BUFSIZE 256 FILE *from; char *buf, *tmp; size_t bufsize, buflength, gotlength; JSString *str; from = stdin; buflength = 0; bufsize = BUFSIZE; buf = JS_malloc(cx, bufsize); if (!buf) return JS_FALSE; while ((gotlength = js_fgets(buf + buflength, bufsize - buflength, from)) > 0) { buflength += gotlength; /* Are we done? */ if (buf[buflength - 1] == '\n') { buf[buflength - 1] = '\0'; break; } /* Else, grow our buffer for another pass. */ tmp = JS_realloc(cx, buf, bufsize * 2); if (!tmp) { JS_free(cx, buf); return JS_FALSE; } bufsize *= 2; buf = tmp; } /* Treat the empty string specially. */ if (buflength == 0) { *rval = JS_GetEmptyStringValue(cx); JS_free(cx, buf); return JS_TRUE; } /* Shrink the buffer to the real size. */ tmp = JS_realloc(cx, buf, buflength); if (!tmp) { JS_free(cx, buf); return JS_FALSE; } buf = tmp; /* * Turn buf into a JSString. Note that buflength includes the trailing null * character. */ str = JS_NewString(cx, buf, buflength - 1); if (!str) { JS_free(cx, buf); return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE;}static JSBoolPrint(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ uintN i, n; JSString *str; for (i = n = 0; i < argc; i++) { str = JS_ValueToString(cx, argv[i]); if (!str) return JS_FALSE; fprintf(gOutFile, "%s%s", i ? " " : "", JS_GetStringBytes(str)); } n++; if (n) fputc('\n', gOutFile); return JS_TRUE;}static JSBoolHelp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);static JSBoolQuit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){#ifdef LIVECONNECT JSJ_SimpleShutdown();#endif JS_ConvertArguments(cx, argc, argv,"/ i", &gExitCode); gQuitting = JS_TRUE; return JS_FALSE;}static JSBoolGC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSRuntime *rt; uint32 preBytes; rt = cx->runtime; preBytes = rt->gcBytes;#ifdef GC_MARK_DEBUG if (argc && JSVAL_IS_STRING(argv[0])) { char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); FILE *file = fopen(name, "w"); if (!file) { fprintf(gErrFile, "gc: can't open %s: %s\n", strerror(errno)); return JS_FALSE; } js_DumpGCHeap = file; } else { js_DumpGCHeap = stdout; }#endif JS_GC(cx);#ifdef GC_MARK_DEBUG if (js_DumpGCHeap != stdout) fclose(js_DumpGCHeap); js_DumpGCHeap = NULL;#endif fprintf(gOutFile, "before %lu, after %lu, break %08lx\n", (unsigned long)preBytes, (unsigned long)rt->gcBytes,#ifdef XP_UNIX (unsigned long)sbrk(0)#else 0#endif );#ifdef JS_GCMETER js_DumpGCStats(rt, stdout);#endif return JS_TRUE;}static JSScript *ValueToScript(JSContext *cx, jsval v){ JSScript *script; JSFunction *fun; if (!JSVAL_IS_PRIMITIVE(v) && JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_ScriptClass) { script = (JSScript *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v)); } else { fun = JS_ValueToFunction(cx, v); if (!fun) return NULL; script = FUN_SCRIPT(fun); } return script;}static JSBoolGetTrapArgs(JSContext *cx, uintN argc, jsval *argv, JSScript **scriptp, int32 *ip){ jsval v; uintN intarg; JSScript *script; *scriptp = cx->fp->down->script; *ip = 0; if (argc != 0) { v = argv[0]; intarg = 0; if (!JSVAL_IS_PRIMITIVE(v) && (JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass || JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_ScriptClass)) { script = ValueToScript(cx, v); if (!script) return JS_FALSE; *scriptp = script; intarg++; } if (argc > intarg) { if (!JS_ValueToInt32(cx, argv[intarg], ip)) return JS_FALSE; } } return JS_TRUE;}static JSTrapStatusTrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void *closure){ JSString *str; JSStackFrame *caller; str = (JSString *) closure; caller = JS_GetScriptedCaller(cx, NULL); if (!JS_EvaluateScript(cx, caller->scopeChain, JS_GetStringBytes(str), JS_GetStringLength(str), caller->script->filename, caller->script->lineno, rval)) { return JSTRAP_ERROR; } if (*rval != JSVAL_VOID) return JSTRAP_RETURN; return JSTRAP_CONTINUE;}static JSBoolTrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSString *str; JSScript *script; int32 i; if (argc == 0) { JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_TRAP_USAGE); return JS_FALSE; } argc--; str = JS_ValueToString(cx, argv[argc]); if (!str) return JS_FALSE; argv[argc] = STRING_TO_JSVAL(str); if (!GetTrapArgs(cx, argc, argv, &script, &i)) return JS_FALSE; return JS_SetTrap(cx, script, script->code + i, TrapHandler, str);}static JSBoolUntrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSScript *script; int32 i; if (!GetTrapArgs(cx, argc, argv, &script, &i)) return JS_FALSE; JS_ClearTrap(cx, script, script->code + i, NULL, NULL); return JS_TRUE;}static JSBoolLineToPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSScript *script; int32 i; uintN lineno; jsbytecode *pc; if (argc == 0) { JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_LINE2PC_USAGE); return JS_FALSE; } script = cx->fp->down->script; if (!GetTrapArgs(cx, argc, argv, &script, &i)) return JS_FALSE; lineno = (i == 0) ? script->lineno : (uintN)i; pc = JS_LineNumberToPC(cx, script, lineno); if (!pc) return JS_FALSE; *rval = INT_TO_JSVAL(PTRDIFF(pc, script->code, jsbytecode)); return JS_TRUE;}static JSBoolPCToLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSScript *script; int32 i; uintN lineno; if (!GetTrapArgs(cx, argc, argv, &script, &i)) return JS_FALSE; lineno = JS_PCToLineNumber(cx, script, script->code + i); if (!lineno) return JS_FALSE; *rval = INT_TO_JSVAL(lineno); return JS_TRUE;}#ifdef DEBUGstatic voidGetSwitchTableBounds(JSScript *script, uintN offset, uintN *start, uintN *end){ jsbytecode *pc; JSOp op; ptrdiff_t jmplen; jsint low, high, n; pc = script->code + offset; op = *pc; switch (op) { case JSOP_TABLESWITCHX: jmplen = JUMPX_OFFSET_LEN; goto jump_table; case JSOP_TABLESWITCH: jmplen = JUMP_OFFSET_LEN; jump_table: pc += jmplen; low = GET_JUMP_OFFSET(pc); pc += JUMP_OFFSET_LEN; high = GET_JUMP_OFFSET(pc); pc += JUMP_OFFSET_LEN; n = high - low + 1; break; case JSOP_LOOKUPSWITCHX: jmplen = JUMPX_OFFSET_LEN; goto lookup_table; default: JS_ASSERT(op == JSOP_LOOKUPSWITCH); jmplen = JUMP_OFFSET_LEN; lookup_table: pc += jmplen; n = GET_ATOM_INDEX(pc); pc += ATOM_INDEX_LEN; jmplen += ATOM_INDEX_LEN; break; } *start = (uintN)(pc - script->code); *end = *start + (uintN)(n * jmplen);}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -