Пример #1
0
bool TypesystemStructHandler::startCommand(Variant::mapType &args)
{
	scope().setFlag(ParserFlag::POST_HEAD, true);

	// Fetch the arguments used for creating this type
	const std::string &structName = args["name"].asString();
	const std::string &parent = args["parent"].asString();

	// Fetch the current typesystem and create the struct node
	Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>();
	Rooted<StructType> structType = typesystem->createStructType(structName);
	structType->setLocation(location());

	// Try to resolve the parent type and set it as parent structure
	if (!parent.empty()) {
		scope().resolve<StructType>(
		    parent, structType, logger(),
		    [](Handle<Node> parent, Handle<Node> structType, Logger &logger) {
			    if (parent != nullptr) {
				    structType.cast<StructType>()->setParentStructure(
				        parent.cast<StructType>(), logger);
			    }
			});
	}
	scope().push(structType);

	return true;
}
Пример #2
0
static inline void
MarkExactStackRootList(JSTracer* trc, Source* s, const char* name)
{
    Rooted<T>* rooter = s->roots.template gcRooters<T>();
    while (rooter) {
        T* addr = rooter->address();
        TraceFn(trc, addr, name);
        rooter = rooter->previous();
    }
}
Пример #3
0
static inline void
MarkExactStackRootList(JSTracer *trc, Source *s, const char *name)
{
    Rooted<T> *rooter = s->template gcRooters<T>();
    while (rooter) {
        T *addr = rooter->address();
        if (!IgnoreExactRoot(addr))
            MarkFunc(trc, addr, name);
        rooter = rooter->previous();
    }
}
Пример #4
0
static void
GatherRooters(Vector<Rooter, 0, SystemAllocPolicy> &rooters,
              Rooted<void*> **thingGCRooters,
              unsigned thingRootKind)
{
    Rooted<void*> *rooter = thingGCRooters[thingRootKind];
    while (rooter) {
        Rooter r = { rooter, ThingRootKind(thingRootKind) };
        JS_ALWAYS_TRUE(rooters.append(r));
        rooter = rooter->previous();
    }
}
Пример #5
0
bool TypesystemEnumHandler::startCommand(Variant::mapType &args)
{
	scope().setFlag(ParserFlag::POST_HEAD, true);

	// Fetch the current typesystem and create the enum node
	Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>();
	Rooted<EnumType> enumType =
	    typesystem->createEnumType(args["name"].asString());
	enumType->setLocation(location());

	scope().push(enumType);

	return true;
}
Пример #6
0
 ~EvalScriptGuard() {
     if (script_) {
         script_->cacheForEval();
         EvalCacheEntry cacheEntry = {script_, lookup_.callerScript, lookup_.pc};
         lookup_.str = lookupStr_;
         if (lookup_.str && IsEvalCacheCandidate(script_))
             cx_->runtime()->evalCache.relookupOrAdd(p_, lookup_, cacheEntry);
     }
 }
Пример #7
0
static inline void
MarkExactStackRooters(JSTracer *trc, Rooted<void*> rooter, ThingRootKind kind)
{
    Rooted<void*> *rooter = cx->thingGCRooters[i];
    while (rooter) {
        MarkExactStackRoot(trc, rooter, ThingRootKind(i));
        rooter = rooter->previous();
    }
}
Пример #8
0
 ~EvalScriptGuard() {
     if (script_) {
         CallDestroyScriptHook(cx_->runtime()->defaultFreeOp(), script_);
         script_->cacheForEval();
         EvalCacheEntry cacheEntry = {script_, lookup_.callerScript, lookup_.pc};
         lookup_.str = lookupStr_;
         if (lookup_.str && IsEvalCacheCandidate(script_))
             cx_->runtime()->evalCache.relookupOrAdd(p_, lookup_, cacheEntry);
     }
 }
Пример #9
0
 ~EvalScriptGuard() {
     if (script_) {
         script_->cacheForEval();
         EvalCacheEntry cacheEntry = {lookupStr_, script_, lookup_.callerScript, lookup_.pc};
         lookup_.str = lookupStr_;
         if (lookup_.str && IsEvalCacheCandidate(script_)) {
             bool ok = cx_->runtime()->evalCache.relookupOrAdd(p_, lookup_, cacheEntry);
             (void)ok; // Ignore failure to add cache entry.
         }
     }
 }
Пример #10
0
bool TypesystemHandler::startCommand(Variant::mapType &args)
{
	// Create the typesystem instance
	Rooted<Typesystem> typesystem =
	    context().getProject()->createTypesystem(args["name"].asString());
	typesystem->setLocation(location());

	// If the typesystem is defined inside a ontology, add a reference to the
	// typesystem to the ontology -- do the same with a document, if no ontology
	// is found
	Rooted<Ontology> ontology = scope().select<Ontology>();
	if (ontology != nullptr) {
		ontology->reference(typesystem);
	} else {
		Rooted<Document> document = scope().select<Document>();
		if (document != nullptr) {
			document->reference(typesystem);
		}
	}

	// Push the typesystem onto the scope, set the POST_HEAD flag to true
	scope().push(typesystem);
	scope().setFlag(ParserFlag::POST_HEAD, false);

	return true;
}
Пример #11
0
 void lookupInEvalCache(JSLinearString *str, JSScript *callerScript, jsbytecode *pc)
 {
     lookupStr_ = str;
     lookup_.str = str;
     lookup_.callerScript = callerScript;
     lookup_.version = cx_->findVersion();
     lookup_.pc = pc;
     p_ = cx_->runtime()->evalCache.lookupForAdd(lookup_);
     if (p_) {
         script_ = p_->script;
         cx_->runtime()->evalCache.remove(p_);
         script_->uncacheForEval();
     }
 }
Пример #12
0
bool TypesystemConstantHandler::startCommand(Variant::mapType &args)
{
	scope().setFlag(ParserFlag::POST_HEAD, true);

	// Read the argument values
	const std::string &constantName = args["name"].asString();
	const std::string &type = args["type"].asString();
	const Variant &value = args["value"];

	Rooted<Typesystem> typesystem = scope().selectOrThrow<Typesystem>();
	Rooted<Constant> constant = typesystem->createConstant(constantName, value);
	constant->setLocation(location());

	// Try to resolve the type
	scope().resolveTypeWithValue(
	    type, constant, constant->getValue(), logger(),
	    [](Handle<Node> type, Handle<Node> constant, Logger &logger) {
		    if (type != nullptr) {
			    constant.cast<Constant>()->setType(type.cast<Type>(), logger);
		    }
		});

	return true;
}
Пример #13
0
bool TypesystemStructFieldHandler::startCommand(Variant::mapType &args)
{
	// Read the argument values
	const std::string &fieldName = args["name"].asString();
	const std::string &type = args["type"].asString();
	const Variant &defaultValue = args["default"];
	const bool optional =
	    !(defaultValue.isObject() && defaultValue.asObject() == nullptr);

	Rooted<StructType> structType = scope().selectOrThrow<StructType>();
	Rooted<Attribute> attribute = structType->createAttribute(
	    fieldName, defaultValue, optional, logger());
	attribute->setLocation(location());

	// Try to resolve the type and default value
	if (optional) {
		scope().resolveTypeWithValue(
		    type, attribute, attribute->getDefaultValue(), logger(),
		    [](Handle<Node> type, Handle<Node> attribute, Logger &logger) {
			    if (type != nullptr) {
				    attribute.cast<Attribute>()->setType(type.cast<Type>(),
				                                         logger);
			    }
			});
	} else {
		scope().resolveType(type, attribute, logger(),
		                    [](Handle<Node> type, Handle<Node> attribute,
		                       Logger &logger) {
			if (type != nullptr) {
				attribute.cast<Attribute>()->setType(type.cast<Type>(), logger);
			}
		});
	}

	return true;
}
Пример #14
0
static inline void
MarkExactStackRooter(JSTracer *trc, Rooted<void*> rooter, ThingRootKind kind)
{
    void **addr = (void **)rooter->address();
    if (!*addr)
        return;

    switch (kind) {
      case THING_ROOT_OBJECT:      MarkObjectRoot(trc, (JSObject **)addr, "exact-object"); break;
      case THING_ROOT_STRING:      MarkStringRoot(trc, (JSSTring **)addr, "exact-string"); break;
      case THING_ROOT_SCRIPT:      MarkScriptRoot(trc, (JSScript **)addr, "exact-script"); break;
      case THING_ROOT_SHAPE:       MarkShapeRoot(trc, (Shape **)addr, "exact-shape"); break;
      case THING_ROOT_BASE_SHAPE:  MarkBaseShapeRoot(trc, (BaseShape **)addr, "exact-baseshape"); break;
      case THING_ROOT_TYPE:        MarkTypeRoot(trc, (types::Type *)addr, "exact-type"); break;
      case THING_ROOT_TYPE_OBJECT: MarkTypeObjectRoot(trc, (types::TypeObject **)addr, "exact-typeobject"); break;
      case THING_ROOT_VALUE:       MarkValueRoot(trc, (Value *)addr, "exact-value"); break;
      case THING_ROOT_ID:          MarkIdRoot(trc, (jsid *)addr, "exact-id"); break;
      case THING_ROOT_PROPERTY_ID: MarkIdRoot(trc, &((js::PropertyId *)addr)->asId(), "exact-propertyid"); break;
      case THING_ROOT_BINDINGS:    ((Bindings *)addr)->trace(trc); break;
      default: JS_NOT_REACHED("Invalid THING_ROOT kind"); break;
    }
}
Пример #15
0
void TypesystemEnumEntryHandler::doHandle(const Variant &fieldData,
                                          Variant::mapType &args)
{
	Rooted<EnumType> enumType = scope().selectOrThrow<EnumType>();
	enumType->addEntry(fieldData.asString(), logger());
}
Пример #16
0
 void setNewScript(JSScript *script) {
     // JSScript::initFromEmitter has already called js_CallNewScriptHook.
     JS_ASSERT(!script_ && script);
     script_ = script;
     script_->setActiveEval();
 }
Пример #17
0
void
JS::CheckStackRoots(JSContext *cx)
{
    JSRuntime *rt = cx->runtime;

    if (rt->gcZeal_ != ZealStackRootingSafeValue && rt->gcZeal_ != ZealStackRootingValue)
        return;
    if (rt->gcZeal_ == ZealStackRootingSafeValue && !rt->gcExactScanningEnabled)
        return;

    // If this assertion fails, it means that an AutoAssertNoGC was placed
    // around code that could trigger GC, and is therefore wrong. The
    // AutoAssertNoGC should be removed and the code it was guarding should be
    // modified to properly root any gcthings, and very possibly any code
    // calling that function should also be modified if it was improperly
    // assuming that GC could not happen at all within the called function.
    // (The latter may not apply if the AutoAssertNoGC only protected a portion
    // of a function, so the callers were already assuming that GC could
    // happen.)
    JS_ASSERT(!InNoGCScope());

    // GCs can't happen when analysis/inference/compilation are active.
    if (cx->compartment->activeAnalysis)
        return;

    // Can switch to the atoms compartment during analysis.
    if (IsAtomsCompartment(cx->compartment)) {
        for (CompartmentsIter c(rt); !c.done(); c.next()) {
            if (c.get()->activeAnalysis)
                return;
        }
    }

    AutoCopyFreeListToArenas copy(rt);

    ConservativeGCData *cgcd = &rt->conservativeGC;
    cgcd->recordStackTop();

    JS_ASSERT(cgcd->hasStackToScan());
    uintptr_t *stackMin, *stackEnd;
#if JS_STACK_GROWTH_DIRECTION > 0
    stackMin = rt->nativeStackBase;
    stackEnd = cgcd->nativeStackTop;
#else
    stackMin = cgcd->nativeStackTop + 1;
    stackEnd = reinterpret_cast<uintptr_t *>(rt->nativeStackBase);
#endif

    // Gather up all of the rooters
    Vector< Rooter, 0, SystemAllocPolicy> rooters;
    for (unsigned i = 0; i < THING_ROOT_LIMIT; i++) {
        Rooted<void*> *rooter = rt->mainThread.thingGCRooters[i];
        while (rooter) {
            Rooter r = { rooter, ThingRootKind(i) };
            JS_ALWAYS_TRUE(rooters.append(r));
            rooter = rooter->previous();
        }
        for (ContextIter cx(rt); !cx.done(); cx.next()) {
            rooter = cx->thingGCRooters[i];
            while (rooter) {
                Rooter r = { rooter, ThingRootKind(i) };
                JS_ALWAYS_TRUE(rooters.append(r));
                rooter = rooter->previous();
            }
        }
    }

    if (SuppressCheckRoots(rooters))
        return;

    // Truncate stackEnd to just after the address of the youngest
    // already-scanned rooter on the stack, to avoid re-scanning the rest of
    // the stack.
    void *firstScanned = NULL;
    for (Rooter *p = rooters.begin(); p != rooters.end(); p++) {
        if (p->rooter->scanned) {
            uintptr_t *addr = reinterpret_cast<uintptr_t*>(p->rooter);
#if JS_STACK_GROWTH_DIRECTION < 0
            if (stackEnd > addr)
#else
            if (stackEnd < addr)
#endif
            {
                stackEnd = addr;
                firstScanned = p->rooter;
            }
        }
    }

    // Partition the stack by the already-scanned start address. Put everything
    // that needs to be searched at the end of the vector.
    Rooter *firstToScan = rooters.begin();
    if (firstScanned) {
        for (Rooter *p = rooters.begin(); p != rooters.end(); p++) {
#if JS_STACK_GROWTH_DIRECTION < 0
            if (p->rooter >= firstScanned)
#else
            if (p->rooter <= firstScanned)
#endif
            {
                Swap(*firstToScan, *p);
                ++firstToScan;
            }
        }
    }

    JS_ASSERT(stackMin <= stackEnd);
    CheckStackRootsRangeAndSkipIon(rt, stackMin, stackEnd, firstToScan, rooters.end());
    CheckStackRootsRange(rt, cgcd->registerSnapshot.words,
                         ArrayEnd(cgcd->registerSnapshot.words),
                         firstToScan, rooters.end());

    // Mark all rooters as scanned
    for (Rooter *p = rooters.begin(); p != rooters.end(); p++)
        p->rooter->scanned = true;
}