/* * Common subroutine of generator_(next|send|throw|close) methods. */ static JSBool generator_op(JSContext *cx, JSGeneratorOp op, jsval *vp, uintN argc) { JSObject *obj; jsval arg; LeaveTrace(cx); obj = JS_THIS_OBJECT(cx, vp); if (!JS_InstanceOf(cx, obj, &js_GeneratorClass, vp + 2)) return JS_FALSE; JSGenerator *gen = (JSGenerator *) obj->getPrivate(); if (!gen) { /* This happens when obj is the generator prototype. See bug 352885. */ goto closed_generator; } if (gen->state == JSGEN_NEWBORN) { switch (op) { case JSGENOP_NEXT: case JSGENOP_THROW: break; case JSGENOP_SEND: if (argc >= 1 && !JSVAL_IS_VOID(vp[2])) { js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND, JSDVG_SEARCH_STACK, vp[2], NULL); return JS_FALSE; } break; default: JS_ASSERT(op == JSGENOP_CLOSE); gen->state = JSGEN_CLOSED; return JS_TRUE; } } else if (gen->state == JSGEN_CLOSED) { closed_generator: switch (op) { case JSGENOP_NEXT: case JSGENOP_SEND: return js_ThrowStopIteration(cx); case JSGENOP_THROW: JS_SetPendingException(cx, argc >= 1 ? vp[2] : JSVAL_VOID); return JS_FALSE; default: JS_ASSERT(op == JSGENOP_CLOSE); return JS_TRUE; } } arg = ((op == JSGENOP_SEND || op == JSGENOP_THROW) && argc != 0) ? vp[2] : JSVAL_VOID; if (!SendToGenerator(cx, op, obj, gen, arg)) return JS_FALSE; *vp = gen->frame.rval; return JS_TRUE; }
CallObject * CallObject::createForFunction(JSContext *cx, StackFrame *fp) { JS_ASSERT(fp->isNonEvalFunctionFrame()); JS_ASSERT(!fp->hasCallObj()); JSObject *scopeChain = &fp->scopeChain(); JS_ASSERT_IF(scopeChain->isWith() || scopeChain->isBlock() || scopeChain->isCall(), scopeChain->getPrivate() != fp); /* * For a named function expression Call's parent points to an environment * object holding function's name. */ if (JSAtom *lambdaName = CallObjectLambdaName(fp->fun())) { scopeChain = DeclEnvObject::create(cx, fp); if (!scopeChain) return NULL; if (!DefineNativeProperty(cx, scopeChain, ATOM_TO_JSID(lambdaName), ObjectValue(fp->callee()), NULL, NULL, JSPROP_PERMANENT | JSPROP_READONLY, 0, 0)) { return NULL; } } CallObject *callobj = create(cx, fp->script(), *scopeChain, &fp->callee()); if (!callobj) return NULL; callobj->setStackFrame(fp); fp->setScopeChainWithOwnCallObj(*callobj); return callobj; }
PerfMeasurement* ExtractPerfMeasurement(jsval wrapper) { if (JSVAL_IS_PRIMITIVE(wrapper)) return 0; // This is what JS_GetInstancePrivate does internally. We can't // call JS_anything from here, because we don't have a JSContext. JSObject *obj = JSVAL_TO_OBJECT(wrapper); if (obj->getClass() != js::Valueify(&pm_class)) return 0; return (PerfMeasurement*) obj->getPrivate(); }
static JSObject * InitErrorClass(JSContext *cx, GlobalObject *global, intN type, JSObject &proto) { JSProtoKey key = GetExceptionProtoKey(type); JSAtom *name = cx->runtime->atomState.classAtoms[key]; JSObject *errorProto = global->createBlankPrototypeInheriting(cx, &ErrorClass, proto); if (!errorProto) return NULL; Value empty = StringValue(cx->runtime->emptyString); jsid nameId = ATOM_TO_JSID(cx->runtime->atomState.nameAtom); jsid messageId = ATOM_TO_JSID(cx->runtime->atomState.messageAtom); jsid fileNameId = ATOM_TO_JSID(cx->runtime->atomState.fileNameAtom); jsid lineNumberId = ATOM_TO_JSID(cx->runtime->atomState.lineNumberAtom); if (!DefineNativeProperty(cx, errorProto, nameId, StringValue(name), JS_PropertyStub, JS_StrictPropertyStub, 0, 0, 0) || !DefineNativeProperty(cx, errorProto, messageId, empty, JS_PropertyStub, JS_StrictPropertyStub, 0, 0, 0) || !DefineNativeProperty(cx, errorProto, fileNameId, empty, JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE, 0, 0) || !DefineNativeProperty(cx, errorProto, lineNumberId, Int32Value(0), JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE, 0, 0)) { return NULL; } /* Create the corresponding constructor. */ JSFunction *ctor = global->createConstructor(cx, Exception, &ErrorClass, name, 1); if (!ctor) return NULL; ctor->setReservedSlot(JSSLOT_ERROR_EXNTYPE, Int32Value(int32(type))); if (!LinkConstructorAndPrototype(cx, ctor, errorProto)) return NULL; if (!DefineConstructorAndPrototype(cx, global, key, ctor, errorProto)) return NULL; JS_ASSERT(!errorProto->getPrivate()); return errorProto; }
RegExpStatics * GlobalObject::getRegExpStatics(ExclusiveContext *cx) const { MOZ_ASSERT(cx); Rooted<GlobalObject*> self(cx, const_cast<GlobalObject*>(this)); JSObject *resObj = nullptr; const Value &val = this->getSlot(REGEXP_STATICS); if (!val.isObject()) { MOZ_ASSERT(val.isUndefined()); resObj = RegExpStatics::create(cx, self); if (!resObj) return nullptr; self->initSlot(REGEXP_STATICS, ObjectValue(*resObj)); } else { resObj = &val.toObject(); } return static_cast<RegExpStatics*>(resObj->getPrivate(/* nfixed = */ 1)); }
JSObject * js_InitExceptionClasses(JSContext *cx, JSObject *obj) { /* * If lazy class initialization occurs for any Error subclass, then all * classes are initialized, starting with Error. To avoid reentry and * redundant initialization, we must not pass a null proto parameter to * NewNonFunction below, when called for the Error superclass. We need to * ensure that Object.prototype is the proto of Error.prototype. * * See the equivalent code to ensure that parent_proto is non-null when * js_InitClass calls NewObject, in jsobj.cpp. */ JSObject *obj_proto; if (!js_GetClassPrototype(cx, obj, JSProto_Object, &obj_proto)) return NULL; /* Define all error constructors. */ Value empty = StringValue(cx->runtime->emptyString); jsid nameId = ATOM_TO_JSID(cx->runtime->atomState.nameAtom); jsid messageId = ATOM_TO_JSID(cx->runtime->atomState.messageAtom); jsid fileNameId = ATOM_TO_JSID(cx->runtime->atomState.fileNameAtom); jsid lineNumberId = ATOM_TO_JSID(cx->runtime->atomState.lineNumberAtom); JSObject *error_proto = NULL; for (intN i = JSEXN_ERR; i != JSEXN_LIMIT; i++) { JSProtoKey protoKey = GetExceptionProtoKey(i); JSAtom *atom = cx->runtime->atomState.classAtoms[protoKey]; JSObject *ctor; JSObject *proto = DefineConstructorAndPrototype(cx, obj, protoKey, atom, (i == JSEXN_ERR) ? obj_proto : error_proto, &js_ErrorClass, Exception, 1, NULL, (i == JSEXN_ERR) ? exception_methods : NULL, NULL, NULL, &ctor); if (!proto) return NULL; JS_ASSERT(proto->getPrivate() == NULL); if (i == JSEXN_ERR) error_proto = proto; /* Save the exception type in a reserved slot. */ if (!ctor->ensureClassReservedSlots(cx)) return NULL; ctor->setReservedSlot(JSSLOT_ERROR_EXNTYPE, Int32Value(int32(i))); /* Add properties to the prototype. */ JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_DECLARING); if (!DefineNativeProperty(cx, proto, nameId, StringValue(atom), PropertyStub, StrictPropertyStub, 0, 0, 0) || !DefineNativeProperty(cx, proto, messageId, empty, PropertyStub, StrictPropertyStub, 0, 0, 0) || !DefineNativeProperty(cx, proto, fileNameId, empty, PropertyStub, StrictPropertyStub, JSPROP_ENUMERATE, 0, 0) || !DefineNativeProperty(cx, proto, lineNumberId, Valueify(JSVAL_ZERO), PropertyStub, StrictPropertyStub, JSPROP_ENUMERATE, 0, 0)) { return NULL; } } return error_proto; }
JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing, JSGCTraceKind kind, bool details) { const char *name = nullptr; /* silence uninitialized warning */ size_t n; if (bufsize == 0) return; switch (kind) { case JSTRACE_OBJECT: { name = static_cast<JSObject *>(thing)->getClass()->name; break; } case JSTRACE_STRING: name = ((JSString *)thing)->isDependent() ? "substring" : "string"; break; case JSTRACE_SCRIPT: name = "script"; break; case JSTRACE_LAZY_SCRIPT: name = "lazyscript"; break; case JSTRACE_JITCODE: name = "jitcode"; break; case JSTRACE_SHAPE: name = "shape"; break; case JSTRACE_BASE_SHAPE: name = "base_shape"; break; case JSTRACE_TYPE_OBJECT: name = "type_object"; break; } n = strlen(name); if (n > bufsize - 1) n = bufsize - 1; js_memcpy(buf, name, n + 1); buf += n; bufsize -= n; *buf = '\0'; if (details && bufsize > 2) { switch (kind) { case JSTRACE_OBJECT: { JSObject *obj = (JSObject *)thing; if (obj->is<JSFunction>()) { JSFunction *fun = &obj->as<JSFunction>(); if (fun->displayAtom()) { *buf++ = ' '; bufsize--; PutEscapedString(buf, bufsize, fun->displayAtom(), 0); } } else if (obj->getClass()->flags & JSCLASS_HAS_PRIVATE) { JS_snprintf(buf, bufsize, " %p", obj->getPrivate()); } else { JS_snprintf(buf, bufsize, " <no private>"); } break; } case JSTRACE_STRING: { *buf++ = ' '; bufsize--; JSString *str = (JSString *)thing; if (str->isLinear()) { bool willFit = str->length() + strlen("<length > ") + CountDecimalDigits(str->length()) < bufsize; n = JS_snprintf(buf, bufsize, "<length %d%s> ", (int)str->length(), willFit ? "" : " (truncated)"); buf += n; bufsize -= n; PutEscapedString(buf, bufsize, &str->asLinear(), 0); } else JS_snprintf(buf, bufsize, "<rope: length %d>", (int)str->length()); break; } case JSTRACE_SCRIPT: { JSScript *script = static_cast<JSScript *>(thing); JS_snprintf(buf, bufsize, " %s:%u", script->filename(), unsigned(script->lineno())); break; } case JSTRACE_LAZY_SCRIPT: case JSTRACE_JITCODE: case JSTRACE_SHAPE: case JSTRACE_BASE_SHAPE: case JSTRACE_TYPE_OBJECT: break; } } buf[bufsize - 1] = '\0'; }