📄 js.c
字号:
OBJ_DROP_PROPERTY(cx, cpx->inner, prop); return JS_TRUE; }#ifdef LAZY_STANDARD_CLASSES if (!(flags & JSRESOLVE_ASSIGNING)) { JSBool resolved; if (!JS_ResolveStandardClass(cx, obj, id, &resolved)) return JS_FALSE; if (resolved) { *objp = obj; return JS_TRUE; } }#endif /* XXX For additional realism, let's resolve some random property here. */ return JS_TRUE;}JS_STATIC_DLL_CALLBACK(void)split_finalize(JSContext *cx, JSObject *obj){ JS_free(cx, JS_GetPrivate(cx, obj));}JS_STATIC_DLL_CALLBACK(uint32)split_mark(JSContext *cx, JSObject *obj, void *arg){ ComplexObject *cpx; cpx = JS_GetPrivate(cx, obj); if (!cpx->isInner && cpx->inner) { /* Mark the inner object. */ JS_MarkGCThing(cx, cpx->inner, "ComplexObject.inner", arg); } return 0;}JS_STATIC_DLL_CALLBACK(JSObject *)split_outerObject(JSContext *cx, JSObject *obj){ ComplexObject *cpx; cpx = JS_GetPrivate(cx, obj); return cpx->isInner ? cpx->outer : obj;}JS_STATIC_DLL_CALLBACK(JSObject *)split_innerObject(JSContext *cx, JSObject *obj){ ComplexObject *cpx; cpx = JS_GetPrivate(cx, obj); return !cpx->isInner ? cpx->inner : obj;}static JSExtendedClass split_global_class = { {"split_global", JSCLASS_NEW_RESOLVE | JSCLASS_HAS_PRIVATE | JSCLASS_IS_EXTENDED, split_addProperty, split_delProperty, split_getProperty, split_setProperty, (JSEnumerateOp)split_enumerate, (JSResolveOp)split_resolve, JS_ConvertStub, split_finalize, NULL, NULL, NULL, NULL, NULL, NULL, split_mark, NULL}, NULL, split_outerObject, split_innerObject, NULL, NULL, NULL, NULL, NULL};JSObject *split_create_outer(JSContext *cx){ ComplexObject *cpx; JSObject *obj; cpx = JS_malloc(cx, sizeof *obj); if (!cpx) return NULL; cpx->outer = NULL; cpx->inner = NULL; cpx->isInner = JS_FALSE; obj = JS_NewObject(cx, &split_global_class.base, NULL, NULL); if (!obj) { JS_free(cx, cpx); return NULL; } JS_ASSERT(!JS_GetParent(cx, obj)); if (!JS_SetPrivate(cx, obj, cpx)) { JS_free(cx, cpx); return NULL; } return obj;}static JSObject *split_create_inner(JSContext *cx, JSObject *outer){ ComplexObject *cpx, *outercpx; JSObject *obj; JS_ASSERT(JS_GET_CLASS(cx, outer) == &split_global_class.base); cpx = JS_malloc(cx, sizeof *cpx); if (!cpx) return NULL; cpx->outer = outer; cpx->inner = NULL; cpx->isInner = JS_TRUE; obj = JS_NewObject(cx, &split_global_class.base, NULL, NULL); if (!obj || !JS_SetParent(cx, obj, NULL) || !JS_SetPrivate(cx, obj, cpx)) { JS_free(cx, cpx); return NULL; } outercpx = JS_GetPrivate(cx, outer); outercpx->inner = obj; return obj;}static ComplexObject *split_get_private(JSContext *cx, JSObject *obj){ do { if (JS_GET_CLASS(cx, obj) == &split_global_class.base) return JS_GetPrivate(cx, obj); obj = JS_GetParent(cx, obj); } while (obj); return NULL;}static JSBoolsandbox_enumerate(JSContext *cx, JSObject *obj){ jsval v; JSBool b; if (!JS_GetProperty(cx, obj, "lazy", &v) || !JS_ValueToBoolean(cx, v, &b)) return JS_FALSE; return !b || JS_EnumerateStandardClasses(cx, obj);}static JSBoolsandbox_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp){ jsval v; JSBool b, resolved; if (!JS_GetProperty(cx, obj, "lazy", &v) || !JS_ValueToBoolean(cx, v, &b)) return JS_FALSE; if (b && (flags & JSRESOLVE_ASSIGNING) == 0) { if (!JS_ResolveStandardClass(cx, obj, id, &resolved)) return JS_FALSE; if (resolved) { *objp = obj; return JS_TRUE; } } *objp = NULL; return JS_TRUE;}static JSClass sandbox_class = { "sandbox", JSCLASS_NEW_RESOLVE, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, sandbox_enumerate, (JSResolveOp)sandbox_resolve, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS};static JSBoolEvalInContext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSString *str; JSObject *sobj; JSContext *scx; const jschar *src; size_t srclen; JSBool lazy, ok; jsval v; JSStackFrame *fp; sobj = NULL; if (!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sobj)) return JS_FALSE; scx = JS_NewContext(JS_GetRuntime(cx), gStackChunkSize); if (!scx) { JS_ReportOutOfMemory(cx); return JS_FALSE; } src = JS_GetStringChars(str); srclen = JS_GetStringLength(str); lazy = JS_FALSE; if (srclen == 4 && src[0] == 'l' && src[1] == 'a' && src[2] == 'z' && src[3] == 'y') { lazy = JS_TRUE; srclen = 0; } if (!sobj) { sobj = JS_NewObject(scx, &sandbox_class, NULL, NULL); if (!sobj || (!lazy && !JS_InitStandardClasses(scx, sobj))) { ok = JS_FALSE; goto out; } v = BOOLEAN_TO_JSVAL(v); ok = JS_SetProperty(cx, sobj, "lazy", &v); if (!ok) goto out; } if (srclen == 0) { *rval = OBJECT_TO_JSVAL(sobj); ok = JS_TRUE; } else { fp = JS_GetScriptedCaller(cx, NULL); ok = JS_EvaluateUCScript(scx, sobj, src, srclen, fp->script->filename, JS_PCToLineNumber(cx, fp->script, fp->pc), rval); }out: JS_DestroyContext(scx); return ok;}static JSFunctionSpec shell_functions[] = { {"version", Version, 0,0,0}, {"options", Options, 0,0,0}, {"load", Load, 1,0,0}, {"readline", ReadLine, 0,0,0}, {"print", Print, 0,0,0}, {"help", Help, 0,0,0}, {"quit", Quit, 0,0,0}, {"gc", GC, 0,0,0}, {"trap", Trap, 3,0,0}, {"untrap", Untrap, 2,0,0}, {"line2pc", LineToPC, 0,0,0}, {"pc2line", PCToLine, 0,0,0}, {"stringsAreUtf8", StringsAreUtf8, 0,0,0}, {"testUtf8", TestUtf8, 1,0,0}, {"throwError", ThrowError, 0,0,0},#ifdef DEBUG {"dis", Disassemble, 1,0,0}, {"dissrc", DisassWithSrc, 1,0,0}, {"notes", Notes, 1,0,0}, {"tracing", Tracing, 0,0,0}, {"stats", DumpStats, 1,0,0},#endif#ifdef TEST_EXPORT {"xport", DoExport, 2,0,0},#endif#ifdef TEST_CVTARGS {"cvtargs", ConvertArgs, 0,0,12},#endif {"build", BuildDate, 0,0,0}, {"clear", Clear, 0,0,0}, {"intern", Intern, 1,0,0}, {"clone", Clone, 1,0,0}, {"seal", Seal, 1,0,1}, {"getpda", GetPDA, 1,0,0}, {"getslx", GetSLX, 1,0,0}, {"toint32", ToInt32, 1,0,0}, {"evalcx", EvalInContext, 1,0,0}, {NULL,NULL,0,0,0}};/* NOTE: These must be kept in sync with the above. */static char *shell_help_messages[] = { "version([number]) Get or set JavaScript version number", "options([option ...]) Get or toggle JavaScript options", "load(['foo.js' ...]) Load files named by string arguments", "readline() Read a single line from stdin", "print([exp ...]) Evaluate and print expressions", "help([name ...]) Display usage and help messages", "quit() Quit the shell", "gc() Run the garbage collector", "trap([fun, [pc,]] exp) Trap bytecode execution", "untrap(fun[, pc]) Remove a trap", "line2pc([fun,] line) Map line number to PC", "pc2line(fun[, pc]) Map PC to line number", "stringsAreUTF8() Check if strings are UTF-8 encoded", "testUTF8(mode) Perform UTF-8 tests (modes are 1 to 4)", "throwError() Throw an error from JS_ReportError",#ifdef DEBUG "dis([fun]) Disassemble functions into bytecodes", "dissrc([fun]) Disassemble functions with source lines", "notes([fun]) Show source notes for functions", "tracing([toggle]) Turn tracing on or off", "stats([string ...]) Dump 'arena', 'atom', 'global' stats",#endif#ifdef TEST_EXPORT "xport(obj, id) Export identified property from object",#endif#ifdef TEST_CVTARGS "cvtargs(b, c, ...) Test JS_ConvertArguments",#endif "build() Show build date and time", "clear([obj]) Clear properties of object", "intern(str) Internalize str in the atom table", "clone(fun[, scope]) Clone function object", "seal(obj[, deep]) Seal object, or object graph if deep", "getpda(obj) Get the property descriptors for obj", "getslx(obj) Get script line extent", "toint32(n) Testing hook for JS_ValueToInt32", "evalcx(s[, o]) Evaluate s in optional sandbox object o\n" " if (s == '' && !o) return new o with eager standard classes\n" " if (s == 'lazy' && !o) return new o with lazy standard classes", 0};static voidShowHelpHeader(void){ fprintf(gOutFile, "%-14s %-22s %s\n", "Command", "Usage", "Description"); fprintf(gOutFile, "%-14s %-22s %s\n", "=======", "=====", "===========");}static voidShowHelpForCommand(uintN n){ fprintf(gOutFile, "%-14.14s %s\n", shell_functions[n].name, shell_help_messages[n]);}static JSObject *split_setup(JSContext *cx){ JSObject *outer, *inner, *arguments; outer = split_create_outer(cx); if (!outer) return NULL; JS_SetGlobalObject(cx, outer); inner = split_create_inner(cx, outer); if (!inner) return NULL; if (!JS_DefineFunctions(cx, inner, shell_functions)) return NULL; JS_ClearScope(cx, outer); /* Create a dummy arguments object. */ arguments = JS_NewArrayObject(cx, 0, NULL); if (!arguments || !JS_DefineProperty(cx, inner, "arguments", OBJECT_TO_JSVAL(arguments), NULL, NULL, 0)) { return NULL; }#ifndef LAZY_STANDARD_CLASSES if (!JS_InitStandardClasses(cx, inner)) return NULL;#endif return inner;}static JSBoolHelp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ uintN i, j; int did_header, did_something; JSType type; JSFunction *fun; JSString *str; const char *bytes; fprintf(gOutFile, "%s\n", JS_GetImplementationVersion()); if (argc == 0) { ShowHelpHeader(); for (i = 0; shell_functions[i].name; i++) ShowHelpForCommand(i); } else { did_header = 0; for (i = 0; i < argc; i++) { did_something = 0; type = JS_TypeOfValue(cx, argv[i]); if (type == JSTYPE_FUNCTION) { fun = JS_ValueToFunction(cx, argv[i]); str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL; } else if (type == JSTYPE_STRING) { str = JSVAL_TO_STRING(argv[i]); } else { str = NULL; } if (str) { bytes = JS_GetStringBytes(str); for (j = 0; shell_functions[j].name; j++) { if (!strcmp(bytes, shell_functions[j].name)) { if (!did_header) { did_header = 1; ShowHelpHeader(); } did_something = 1; ShowHelpForCommand(j); break; } } } if (!did_something) { str = JS_ValueToString(cx, argv[i]); if (!str) return JS_FALSE; fprintf(gErrFile, "Sorry, no help for %s\n", JS_GetStringBytes(str)); } } } return JS_TRUE;}/* * Define a JS object called "it". Give it class operations that printf why * they're being called for tutorial purposes. */enum its_tinyid { ITS_COLOR, ITS_HEIGHT, ITS_WIDTH, ITS_FUNNY, ITS_ARRAY, ITS_RDONLY};static JSPropertySpec its_props[] = { {"color", ITS_COLOR, JSPROP_ENUMERATE, NULL, NULL}, {"height", ITS_HEIGHT, JSPROP_ENUMERATE, NULL, NULL}, {"width", ITS_WIDTH, JSPROP_ENUMERATE, NULL, NULL}, {"funny", ITS_FUNNY, JSPROP_ENUMERATE, NULL, NULL}, {"array", ITS_ARRAY, JSPROP_ENUMERATE, NULL, NULL}, {"rdonly", ITS_RDONLY, JSPROP_READONLY, NULL, NULL}, {NULL,0,0,NULL,NULL}};static JSBoolits_item(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ *rval = OBJECT_TO_JSVAL(obj); if (argc != 0) JS_SetCallReturnValue2(cx, argv[0]); return JS_TRUE;}static JSBoolits_bindMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ char *name; JSObject *method; if (!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -