static void UnmapPages(void *addr, size_t size) { #ifdef SOLARIS JS_ALWAYS_TRUE(munmap((caddr_t) addr, size) == 0); #else JS_ALWAYS_TRUE(munmap(addr, size) == 0); #endif }
static void * MapAlignedPages(size_t size, size_t alignment) { int recursions = -1; /* make up to OS2_MAX_RECURSIONS attempts to get an aligned block * of the right size by recursively allocating blocks of unaligned * free memory until only an aligned allocation is possible */ void *p = MapAlignedPagesRecursively(size, alignment, recursions); if (p) return p; /* if memory is heavily fragmented, the recursive strategy may fail; * instead, use the "expensive" strategy: allocate twice as much * as requested and return an aligned address within this block */ if (DosAllocMem(&p, 2 * size, OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE)) { JS_ALWAYS_TRUE(DosAllocMem(&p, 2 * size, PAG_COMMIT | PAG_READ | PAG_WRITE) == 0); } jsuword addr = reinterpret_cast<jsuword>(p); addr = (addr + (alignment - 1)) & ~(alignment - 1); return reinterpret_cast<void *>(addr); }
static void UnmapPages(void *addr, size_t size) { JS_ALWAYS_TRUE(vm_deallocate((vm_map_t) mach_task_self(), (vm_address_t) addr, (vm_size_t) size) == KERN_SUCCESS); }
static void * MapAlignedPagesRecursively(size_t size, size_t alignment, int& recursions) { if (++recursions >= OS2_MAX_RECURSIONS) return NULL; void *tmp; if (DosAllocMem(&tmp, size, OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE)) { JS_ALWAYS_TRUE(DosAllocMem(&tmp, size, PAG_COMMIT | PAG_READ | PAG_WRITE) == 0); } size_t offset = reinterpret_cast<jsuword>(tmp) & (alignment - 1); if (!offset) return tmp; /* if there are 'filler' bytes of free space above 'tmp', free 'tmp', * then reallocate it as a 'filler'-sized block; assuming we're not * in a race with another thread, the next recursion should succeed */ size_t filler = size + alignment - offset; unsigned long cb = filler; unsigned long flags = 0; unsigned long rc = DosQueryMem(&(static_cast<char*>(tmp))[size], &cb, &flags); if (!rc && (flags & PAG_FREE) && cb >= filler) { UnmapPages(tmp, 0); if (DosAllocMem(&tmp, filler, OBJ_ANY | PAG_COMMIT | PAG_READ | PAG_WRITE)) { JS_ALWAYS_TRUE(DosAllocMem(&tmp, filler, PAG_COMMIT | PAG_READ | PAG_WRITE) == 0); } } void *p = MapAlignedPagesRecursively(size, alignment, recursions); UnmapPages(tmp, 0); return p; }
NS_IMETHODIMP SmsManager::Send(const jsval& aNumber, const nsAString& aMessage, jsval* aReturn) { nsresult rv; nsIScriptContext* sc = GetContextForEventHandlers(&rv); NS_ENSURE_STATE(sc); AutoPushJSContext cx(sc->GetNativeContext()); NS_ASSERTION(cx, "Failed to get a context!"); if (!aNumber.isString() && !(aNumber.isObject() && JS_IsArrayObject(cx, &aNumber.toObject()))) { return NS_ERROR_INVALID_ARG; } JSObject* global = sc->GetNativeGlobal(); NS_ASSERTION(global, "Failed to get global object!"); JSAutoRequest ar(cx); JSAutoCompartment ac(cx, global); if (aNumber.isString()) { return Send(cx, global, aNumber.toString(), aMessage, aReturn); } // Must be an array then. JSObject& numbers = aNumber.toObject(); uint32_t size; JS_ALWAYS_TRUE(JS_GetArrayLength(cx, &numbers, &size)); jsval* requests = new jsval[size]; for (uint32_t i=0; i<size; ++i) { jsval number; if (!JS_GetElement(cx, &numbers, i, &number)) { return NS_ERROR_INVALID_ARG; } nsresult rv = Send(cx, global, number.toString(), aMessage, &requests[i]); NS_ENSURE_SUCCESS(rv, rv); } aReturn->setObjectOrNull(JS_NewArrayObject(cx, size, requests)); NS_ENSURE_TRUE(aReturn->isObject(), NS_ERROR_FAILURE); return NS_OK; }
static void * MapPages(void *addr, size_t size) { /* * We don't use MAP_FIXED here, because it can cause the *replacement* * of existing mappings, and we only want to create new mappings. */ void *p = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (p == MAP_FAILED) return NULL; if (addr && p != addr) { /* We succeeded in mapping memory, but not in the right place. */ JS_ALWAYS_TRUE(munmap(p, size) == 0); return NULL; } return p; }
// static XPCWrappedNativeScope* XPCWrappedNativeScope::GetNewOrUsed(XPCCallContext& ccx, JSObject* aGlobal) { XPCWrappedNativeScope* scope = FindInJSObjectScope(ccx, aGlobal, true); if (!scope) scope = new XPCWrappedNativeScope(ccx, aGlobal); else { // We need to call SetGlobal in order to refresh our cached // mPrototypeJSObject and to clear mPrototypeNoHelper (so we get a new // new one if requested in the new scope) in the case where the global // object is being reused (JS_ClearScope has been called). NOTE: We are // only called by nsXPConnect::InitClasses. scope->SetGlobal(ccx, aGlobal); } if (js::GetObjectClass(aGlobal)->flags & JSCLASS_XPCONNECT_GLOBAL) JS_ALWAYS_TRUE(JS_SetReservedSlot(ccx, aGlobal, JSCLASS_GLOBAL_SLOT_COUNT, PRIVATE_TO_JSVAL(scope))); return scope; }
static JSScript * CompileScriptForPrincipalsVersionOrigin(JSContext *cx, JS::HandleObject obj, JSPrincipals *principals, JSPrincipals *originPrincipals, const char *bytes, size_t nbytes, const char *filename, unsigned lineno, JSVersion version) { size_t nchars; if (!JS_DecodeBytes(cx, bytes, nbytes, NULL, &nchars)) return NULL; jschar *chars = static_cast<jschar *>(JS_malloc(cx, nchars * sizeof(jschar))); if (!chars) return NULL; JS_ALWAYS_TRUE(JS_DecodeBytes(cx, bytes, nbytes, chars, &nchars)); JSScript *script = JS_CompileUCScriptForPrincipalsVersionOrigin(cx, obj, principals, originPrincipals, chars, nchars, filename, lineno, version); free(chars); return script; }
static JSScript * CompileScriptForPrincipalsVersionOrigin(JSContext *cx, JS::HandleObject obj, JSPrincipals *originPrincipals, const char *bytes, size_t nbytes, const char *filename, unsigned lineno, JSVersion version) { size_t nchars; if (!JS_DecodeBytes(cx, bytes, nbytes, nullptr, &nchars)) return nullptr; jschar *chars = static_cast<jschar *>(JS_malloc(cx, nchars * sizeof(jschar))); if (!chars) return nullptr; JS_ALWAYS_TRUE(JS_DecodeBytes(cx, bytes, nbytes, chars, &nchars)); JS::CompileOptions options(cx); options.setOriginPrincipals(originPrincipals) .setFileAndLine(filename, lineno) .setVersion(version); JSScript *script = JS::Compile(cx, obj, options, chars, nchars); free(chars); return script; }
static void UnmapPagesAtBase(void *p) { JS_ALWAYS_TRUE(VirtualFree(p, 0, MEM_RELEASE)); }
static void UnmapPages(void *addr, size_t size) { JS_ALWAYS_TRUE(VirtualFree(addr, 0, MEM_RELEASE)); }
JSObject * GlobalObject::initFunctionAndObjectClasses(JSContext *cx) { Rooted<GlobalObject*> self(cx, this); JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment); JS_ASSERT(isNative()); /* * Calling a function from a cleared global triggers this (yeah, I know). * Uncomment this once bug 470510 is fixed (if that bug doesn't remove * isCleared entirely). */ // JS_ASSERT(!isCleared()); /* If cx has no global object, make this the global object. */ if (!cx->globalObject) JS_SetGlobalObject(cx, self); RootedObject objectProto(cx); /* * Create |Object.prototype| first, mirroring CreateBlankProto but for the * prototype of the created object. */ objectProto = NewObjectWithGivenProto(cx, &ObjectClass, NULL, self); if (!objectProto || !objectProto->setSingletonType(cx)) return NULL; /* * The default 'new' type of Object.prototype is required by type inference * to have unknown properties, to simplify handling of e.g. heterogenous * objects in JSON and script literals. */ if (!objectProto->setNewTypeUnknown(cx)) return NULL; /* Create |Function.prototype| next so we can create other functions. */ RootedFunction functionProto(cx); { JSObject *functionProto_ = NewObjectWithGivenProto(cx, &FunctionClass, objectProto, self); if (!functionProto_) return NULL; functionProto = functionProto_->toFunction(); /* * Bizarrely, |Function.prototype| must be an interpreted function, so * give it the guts to be one. */ JSObject *proto = js_NewFunction(cx, functionProto, NULL, 0, JSFUN_INTERPRETED, self, NULL); if (!proto) return NULL; JS_ASSERT(proto == functionProto); functionProto->flags |= JSFUN_PROTOTYPE; const char *rawSource = "() {\n}"; size_t sourceLen = strlen(rawSource); jschar *source = InflateString(cx, rawSource, &sourceLen); if (!source) return NULL; ScriptSource *ss = cx->new_<ScriptSource>(); if (!ss) { cx->free_(source); return NULL; } JS_ALWAYS_TRUE(ss->setSource(cx, source, sourceLen, false, NULL, true)); CompileOptions options(cx); options.setNoScriptRval(true) .setVersion(JSVERSION_DEFAULT); Rooted<JSScript*> script(cx, JSScript::Create(cx, /* enclosingScope = */ NullPtr(), /* savedCallerFun = */ false, options, /* staticLevel = */ 0, ss, 0, ss->length())); ss->attachToRuntime(cx->runtime); if (!script || !JSScript::fullyInitTrivial(cx, script)) return NULL; functionProto->initScript(script); functionProto->getType(cx)->interpretedFunction = functionProto; script->setFunction(functionProto); if (!functionProto->setSingletonType(cx)) return NULL; /* * The default 'new' type of Function.prototype is required by type * inference to have unknown properties, to simplify handling of e.g. * CloneFunctionObject. */ if (!functionProto->setNewTypeUnknown(cx)) return NULL; } /* Create the Object function now that we have a [[Prototype]] for it. */ RootedFunction objectCtor(cx); { JSObject *ctor = NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self); if (!ctor) return NULL; objectCtor = js_NewFunction(cx, ctor, js_Object, 1, JSFUN_CONSTRUCTOR, self, CLASS_NAME(cx, Object)); if (!objectCtor) return NULL; } /* * Install |Object| and |Object.prototype| for the benefit of subsequent * code that looks for them. */ self->setObjectClassDetails(objectCtor, objectProto); /* Create |Function| so it and |Function.prototype| can be installed. */ RootedFunction functionCtor(cx); { // Note that ctor is rooted purely for the JS_ASSERT at the end RootedObject ctor(cx, NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self)); if (!ctor) return NULL; functionCtor = js_NewFunction(cx, ctor, Function, 1, JSFUN_CONSTRUCTOR, self, CLASS_NAME(cx, Function)); if (!functionCtor) return NULL; JS_ASSERT(ctor == functionCtor); } /* * Install |Function| and |Function.prototype| so that we can freely create * functions and objects without special effort. */ self->setFunctionClassDetails(functionCtor, functionProto); /* * The hard part's done: now go back and add all the properties these * primordial values have. */ if (!LinkConstructorAndPrototype(cx, objectCtor, objectProto) || !DefinePropertiesAndBrand(cx, objectProto, NULL, object_methods)) { return NULL; } /* * Add an Object.prototype.__proto__ accessor property to implement that * extension (if it's actually enabled). Cache the getter for this * function so that cross-compartment [[Prototype]]-getting is implemented * in one place. */ Rooted<JSFunction*> getter(cx, js_NewFunction(cx, NULL, ProtoGetter, 0, 0, self, NULL)); if (!getter) return NULL; #if JS_HAS_OBJ_PROTO_PROP Rooted<JSFunction*> setter(cx, js_NewFunction(cx, NULL, ProtoSetter, 0, 0, self, NULL)); if (!setter) return NULL; RootedValue undefinedValue(cx, UndefinedValue()); if (!objectProto->defineProperty(cx, cx->runtime->atomState.protoAtom, undefinedValue, JS_DATA_TO_FUNC_PTR(PropertyOp, getter.get()), JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setter.get()), JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED)) { return NULL; } #endif /* JS_HAS_OBJ_PROTO_PROP */ self->setProtoGetter(getter); if (!DefinePropertiesAndBrand(cx, objectCtor, NULL, object_static_methods) || !LinkConstructorAndPrototype(cx, functionCtor, functionProto) || !DefinePropertiesAndBrand(cx, functionProto, NULL, function_methods) || !DefinePropertiesAndBrand(cx, functionCtor, NULL, NULL)) { return NULL; } /* Add the global Function and Object properties now. */ jsid objectId = NameToId(CLASS_NAME(cx, Object)); if (!self->addDataProperty(cx, objectId, JSProto_Object + JSProto_LIMIT * 2, 0)) return NULL; jsid functionId = NameToId(CLASS_NAME(cx, Function)); if (!self->addDataProperty(cx, functionId, JSProto_Function + JSProto_LIMIT * 2, 0)) return NULL; /* Heavy lifting done, but lingering tasks remain. */ /* ES5 15.1.2.1. */ RootedId id(cx, NameToId(cx->runtime->atomState.evalAtom)); JSObject *evalobj = js_DefineFunction(cx, self, id, IndirectEval, 1, JSFUN_STUB_GSOPS); if (!evalobj) return NULL; self->setOriginalEval(evalobj); /* ES5 13.2.3: Construct the unique [[ThrowTypeError]] function object. */ RootedFunction throwTypeError(cx, js_NewFunction(cx, NULL, ThrowTypeError, 0, 0, self, NULL)); if (!throwTypeError) return NULL; if (!throwTypeError->preventExtensions(cx)) return NULL; self->setThrowTypeError(throwTypeError); RootedObject intrinsicsHolder(cx, JS_NewObject(cx, NULL, NULL, self)); if (!intrinsicsHolder) return NULL; self->setIntrinsicsHolder(intrinsicsHolder); if (!JS_DefineFunctions(cx, intrinsicsHolder, intrinsic_functions)) return NULL; /* * The global object should have |Object.prototype| as its [[Prototype]]. * Eventually we'd like to have standard classes be there from the start, * and thus we would know we were always setting what had previously been a * null [[Prototype]], but right now some code assumes it can set the * [[Prototype]] before standard classes have been initialized. For now, * only set the [[Prototype]] if it hasn't already been set. */ if (self->shouldSplicePrototype(cx) && !self->splicePrototype(cx, objectProto)) return NULL; /* * Notify any debuggers about the creation of the script for * |Function.prototype| -- after all initialization, for simplicity. */ js_CallNewScriptHook(cx, functionProto->script(), functionProto); return functionProto; }