Example #1
0
File: init.c Project: smunix/ldc
Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
{
    int errors = 0;

    //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
    vars.setDim(field.dim);
    t = t->toBasetype();
    if (t->ty == Tstruct)
    {
        unsigned fieldi = 0;

        TypeStruct *ts = (TypeStruct *)t;
        ad = ts->sym;
        if (ad->ctor)
            error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
                ad->kind(), ad->toChars(), ad->toChars());
        size_t nfields = ad->fields.dim;
        if (((StructDeclaration *)ad)->isnested) nfields--;
        for (size_t i = 0; i < field.dim; i++)
        {
            Identifier *id = field.tdata()[i];
            Initializer *val = value.tdata()[i];
            Dsymbol *s;
            VarDeclaration *v;

            if (id == NULL)
            {
                if (fieldi >= nfields)
                {   error(loc, "too many initializers for %s", ad->toChars());
                    errors = 1;
                    field.remove(i);
                    i--;
                    continue;
                }
                else
                {
                    s = ad->fields.tdata()[fieldi];
                }
            }
            else
            {
                //s = ad->symtab->lookup(id);
                s = ad->search(loc, id, 0);
                if (!s)
                {
                    error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
                    errors = 1;
                    continue;
                }

                // Find out which field index it is
                for (fieldi = 0; 1; fieldi++)
                {
                    if (fieldi >= nfields)
                    {
                        error(loc, "%s.%s is not a per-instance initializable field",
                            t->toChars(), s->toChars());
                        errors = 1;
                        break;
                    }
                    if (s == ad->fields.tdata()[fieldi])
                        break;
                }
            }
            if (s && (v = s->isVarDeclaration()) != NULL)
            {
                val = val->semantic(sc, v->type, needInterpret);
                value.tdata()[i] = val;
                vars.tdata()[i] = v;
            }
            else
            {   error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars());
                errors = 1;
            }
            fieldi++;
        }
    }
    else if (t->ty == Tdelegate && value.dim == 0)
    {   /* Rewrite as empty delegate literal { }
         */
        Parameters *arguments = new Parameters;
        Type *tf = new TypeFunction(arguments, NULL, 0, LINKd);
        FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, TOKdelegate, NULL);
        fd->fbody = new CompoundStatement(loc, new Statements());
        fd->endloc = loc;
        Expression *e = new FuncExp(loc, fd);
        ExpInitializer *ie = new ExpInitializer(loc, e);
        return ie->semantic(sc, t, needInterpret);
    }
    else
    {
        error(loc, "a struct is not a valid initializer for a %s", t->toChars());
        errors = 1;
    }
    if (errors)
    {
        field.setDim(0);
        value.setDim(0);
        vars.setDim(0);
    }
    return this;
}
Example #2
0
size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
{
    ASSERT(!propertyName.isNull());
    ASSERT(get(propertyName) == notFound);

    checkConsistency();

    if (attributes & DontEnum)
        m_hasNonEnumerableProperties = true;

    UString::Rep* rep = propertyName._ustring.rep();

    if (!m_propertyTable)
        createPropertyMapHashTable();

    // FIXME: Consider a fast case for tables with no deleted sentinels.

    unsigned i = rep->existingHash();
    unsigned k = 0;
    bool foundDeletedElement = false;
    unsigned deletedElementIndex = 0; // initialize to make the compiler happy

#if DUMP_PROPERTYMAP_STATS
    ++numProbes;
#endif

    while (1) {
        unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
        if (entryIndex == emptyEntryIndex)
            break;

        if (entryIndex == deletedSentinelIndex) {
            // If we find a deleted-element sentinel, remember it for use later.
            if (!foundDeletedElement) {
                foundDeletedElement = true;
                deletedElementIndex = i;
            }
        }

        if (k == 0) {
            k = 1 | doubleHash(rep->existingHash());
#if DUMP_PROPERTYMAP_STATS
            ++numCollisions;
#endif
        }

        i += k;

#if DUMP_PROPERTYMAP_STATS
        ++numRehashes;
#endif
    }

    // Figure out which entry to use.
    unsigned entryIndex = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount + 2;
    if (foundDeletedElement) {
        i = deletedElementIndex;
        --m_propertyTable->deletedSentinelCount;

        // Since we're not making the table bigger, we can't use the entry one past
        // the end that we were planning on using, so search backwards for the empty
        // slot that we can use. We know it will be there because we did at least one
        // deletion in the past that left an entry empty.
        while (m_propertyTable->entries()[--entryIndex - 1].key) { }
    }

    // Create a new hash table entry.
    m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex;

    // Create a new hash table entry.
    rep->ref();
    m_propertyTable->entries()[entryIndex - 1].key = rep;
    m_propertyTable->entries()[entryIndex - 1].attributes = attributes;
    m_propertyTable->entries()[entryIndex - 1].specificValue = specificValue;
    m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed;

    unsigned newOffset;
    if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) {
        newOffset = m_propertyTable->deletedOffsets->last();
        m_propertyTable->deletedOffsets->removeLast();
    } else
        newOffset = m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount;
    m_propertyTable->entries()[entryIndex - 1].offset = newOffset;

    ++m_propertyTable->keyCount;

    if ((m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount) * 2 >= m_propertyTable->size)
        expandPropertyMapHashTable();

    checkConsistency();
    return newOffset;
}
Example #3
0
AST::AST(){
    root = new PackageDeclaration(NULL, NULL, SourceLocation(), DeclarationQualifier());
    Identifier *id = root->getScope()->getInScope("__root");
    id->addDeclaration(root, Identifier::ID_PACKAGE);
    root->identifier = id; //XXX bit hacky
}
bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    // Never allow cross-domain getOwnPropertyDescriptor
    if (!allowsAccessFrom(exec))
        return false;

    const HashEntry* entry;
    
    // We don't want any properties other than "close" and "closed" on a closed window.
    if (!impl()->frame()) {
        // The following code is safe for cross-domain and same domain use.
        // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype).
        entry = s_info.propHashTable(exec)->entry(exec, propertyName);
        if (entry && !(entry->attributes() & Function) && entry->propertyGetter() == jsDOMWindowClosed) {
            descriptor.setDescriptor(jsBoolean(true), ReadOnly | DontDelete | DontEnum);
            return true;
        }
        entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
        if (entry && (entry->attributes() & Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) {
            PropertySlot slot;
            slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
            descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
            return true;
        }
        descriptor.setUndefined();
        return true;
    }

    entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName);
    if (entry) {
        PropertySlot slot;
        slot.setCustom(this, entry->propertyGetter());
        descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
        return true;
    }
    
    // Check for child frames by name before built-in properties to
    // match Mozilla. This does not match IE, but some sites end up
    // naming frames things that conflict with window properties that
    // are in Moz but not IE. Since we have some of these, we have to do
    // it the Moz way.
    if (impl()->frame()->tree()->child(identifierToAtomicString(propertyName))) {
        PropertySlot slot;
        slot.setCustom(this, childFrameGetter);
        descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
        return true;
    }
    
    bool ok;
    unsigned i = propertyName.toArrayIndex(ok);
    if (ok && i < impl()->frame()->tree()->childCount()) {
        PropertySlot slot;
        slot.setCustomIndex(this, i, indexGetter);
        descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
        return true;
    }

    // Allow shortcuts like 'Image1' instead of document.images.Image1
    Document* document = impl()->frame()->document();
    if (document->isHTMLDocument()) {
        AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
        if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) {
            PropertySlot slot;
            slot.setCustom(this, namedItemGetter);
            descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
            return true;
        }
    }
    
    return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
Example #5
0
Expression *semanticTraits(TraitsExp *e, Scope *sc)
{
#if LOGSEMANTIC
    printf("TraitsExp::semantic() %s\n", e->toChars());
#endif
    if (e->ident != Id::compiles && e->ident != Id::isSame &&
        e->ident != Id::identifier && e->ident != Id::getProtection)
    {
        if (!TemplateInstance::semanticTiargs(e->loc, sc, e->args, 1))
            return new ErrorExp();
    }
    size_t dim = e->args ? e->args->dim : 0;

    if (e->ident == Id::isArithmetic)
    {
        return isTypeX(e, &isTypeArithmetic);
    }
    else if (e->ident == Id::isFloating)
    {
        return isTypeX(e, &isTypeFloating);
    }
    else if (e->ident == Id::isIntegral)
    {
        return isTypeX(e, &isTypeIntegral);
    }
    else if (e->ident == Id::isScalar)
    {
        return isTypeX(e, &isTypeScalar);
    }
    else if (e->ident == Id::isUnsigned)
    {
        return isTypeX(e, &isTypeUnsigned);
    }
    else if (e->ident == Id::isAssociativeArray)
    {
        return isTypeX(e, &isTypeAssociativeArray);
    }
    else if (e->ident == Id::isStaticArray)
    {
        return isTypeX(e, &isTypeStaticArray);
    }
    else if (e->ident == Id::isAbstractClass)
    {
        return isTypeX(e, &isTypeAbstractClass);
    }
    else if (e->ident == Id::isFinalClass)
    {
        return isTypeX(e, &isTypeFinalClass);
    }
    else if (e->ident == Id::isPOD)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Type *t = isType(o);
        StructDeclaration *sd;
        if (!t)
        {
            e->error("type expected as second argument of __traits %s instead of %s", e->ident->toChars(), o->toChars());
            goto Lfalse;
        }
        Type *tb = t->baseElemOf();
        if (tb->ty == Tstruct
            && ((sd = (StructDeclaration *)(((TypeStruct *)tb)->sym)) != NULL))
        {
            if (sd->isPOD())
                goto Ltrue;
            else
                goto Lfalse;
        }
        goto Ltrue;
    }
    else if (e->ident == Id::isNested)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        AggregateDeclaration *a;
        FuncDeclaration *f;

        if (!s) { }
        else if ((a = s->isAggregateDeclaration()) != NULL)
        {
            if (a->isNested())
                goto Ltrue;
            else
                goto Lfalse;
        }
        else if ((f = s->isFuncDeclaration()) != NULL)
        {
            if (f->isNested())
                goto Ltrue;
            else
                goto Lfalse;
        }

        e->error("aggregate or function expected instead of '%s'", o->toChars());
        goto Lfalse;
    }
    else if (e->ident == Id::isAbstractFunction)
    {
        return isFuncX(e, &isFuncAbstractFunction);
    }
    else if (e->ident == Id::isVirtualFunction)
    {
        return isFuncX(e, &isFuncVirtualFunction);
    }
    else if (e->ident == Id::isVirtualMethod)
    {
        return isFuncX(e, &isFuncVirtualMethod);
    }
    else if (e->ident == Id::isFinalFunction)
    {
        return isFuncX(e, &isFuncFinalFunction);
    }
    else if (e->ident == Id::isOverrideFunction)
    {
        return isFuncX(e, &isFuncOverrideFunction);
    }
    else if (e->ident == Id::isStaticFunction)
    {
        return isFuncX(e, &isFuncStaticFunction);
    }
    else if (e->ident == Id::isRef)
    {
        return isDeclX(e, &isDeclRef);
    }
    else if (e->ident == Id::isOut)
    {
        return isDeclX(e, &isDeclOut);
    }
    else if (e->ident == Id::isLazy)
    {
        return isDeclX(e, &isDeclLazy);
    }
    else if (e->ident == Id::identifier)
    {
        // Get identifier for symbol as a string literal
        /* Specify 0 for bit 0 of the flags argument to semanticTiargs() so that
         * a symbol should not be folded to a constant.
         * Bit 1 means don't convert Parameter to Type if Parameter has an identifier
         */
        if (!TemplateInstance::semanticTiargs(e->loc, sc, e->args, 2))
            return new ErrorExp();

        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Parameter *po = isParameter(o);
        Identifier *id;
        if (po)
        {
            id = po->ident;
            assert(id);
        }
        else
        {
            Dsymbol *s = getDsymbol(o);
            if (!s || !s->ident)
            {
                e->error("argument %s has no identifier", o->toChars());
                goto Lfalse;
            }
            id = s->ident;
        }
        StringExp *se = new StringExp(e->loc, id->toChars());
        return se->semantic(sc);
    }
    else if (e->ident == Id::getProtection)
    {
        if (dim != 1)
            goto Ldimerror;

        Scope *sc2 = sc->push();
        sc2->flags = sc->flags | SCOPEnoaccesscheck;
        bool ok = TemplateInstance::semanticTiargs(e->loc, sc2, e->args, 1);
        sc2->pop();

        if (!ok)
            return new ErrorExp();

        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        if (!s)
        {
            if (!isError(o))
                e->error("argument %s has no protection", o->toChars());
            goto Lfalse;
        }
        if (s->scope)
            s->semantic(s->scope);
        PROT protection = s->prot();

        const char *protName = Pprotectionnames[protection];

        assert(protName);
        StringExp *se = new StringExp(e->loc, (char *) protName);
        return se->semantic(sc);
    }
    else if (e->ident == Id::parent)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        if (s)
        {
            if (FuncDeclaration *fd = s->isFuncDeclaration())   // Bugzilla 8943
                s = fd->toAliasFunc();
            if (!s->isImport())  // Bugzilla 8922
                s = s->toParent();
        }
        if (!s || s->isImport())
        {
            e->error("argument %s has no parent", o->toChars());
            goto Lfalse;
        }

        if (FuncDeclaration *f = s->isFuncDeclaration())
        {
            if (TemplateDeclaration *td = getFuncTemplateDecl(f))
            {
                if (td->overroot)       // if not start of overloaded list of TemplateDeclaration's
                    td = td->overroot;  // then get the start
                Expression *ex = new TemplateExp(e->loc, td, f);
                ex = ex->semantic(sc);
                return ex;
            }

            if (FuncLiteralDeclaration *fld = f->isFuncLiteralDeclaration())
            {
                // Directly translate to VarExp instead of FuncExp
                Expression *ex = new VarExp(e->loc, fld, 1);
                return ex->semantic(sc);
            }
        }

        return (new DsymbolExp(e->loc, s))->semantic(sc);
    }
    else if (e->ident == Id::hasMember ||
             e->ident == Id::getMember ||
             e->ident == Id::getOverloads ||
             e->ident == Id::getVirtualMethods ||
             e->ident == Id::getVirtualFunctions)
    {
        if (dim != 2)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Expression *ex = isExpression((*e->args)[1]);
        if (!ex)
        {
            e->error("expression expected as second argument of __traits %s", e->ident->toChars());
            goto Lfalse;
        }
        ex = ex->ctfeInterpret();
        StringExp *se = ex->toStringExp();
        if (!se || se->length() == 0)
        {
            e->error("string expected as second argument of __traits %s instead of %s", e->ident->toChars(), ex->toChars());
            goto Lfalse;
        }
        se = se->toUTF8(sc);
        if (se->sz != 1)
        {
            e->error("string must be chars");
            goto Lfalse;
        }
        Identifier *id = Lexer::idPool((char *)se->string);

        /* Prefer dsymbol, because it might need some runtime contexts.
         */
        Dsymbol *sym = getDsymbol(o);
        if (sym)
        {
            ex = new DsymbolExp(e->loc, sym);
            ex = new DotIdExp(e->loc, ex, id);
        }
        else if (Type *t = isType(o))
            ex = typeDotIdExp(e->loc, t, id);
        else if (Expression *ex2 = isExpression(o))
            ex = new DotIdExp(e->loc, ex2, id);
        else
        {
            e->error("invalid first argument");
            goto Lfalse;
        }

        if (e->ident == Id::hasMember)
        {
            if (sym)
            {
                Dsymbol *sm = sym->search(e->loc, id);
                if (sm)
                    goto Ltrue;
            }

            /* Take any errors as meaning it wasn't found
             */
            Scope *sc2 = sc->push();
            ex = ex->trySemantic(sc2);
            sc2->pop();
            if (!ex)
                goto Lfalse;
            else
                goto Ltrue;
        }
        else if (e->ident == Id::getMember)
        {
            ex = ex->semantic(sc);
            return ex;
        }
        else if (e->ident == Id::getVirtualFunctions ||
                 e->ident == Id::getVirtualMethods ||
                 e->ident == Id::getOverloads)
        {
            unsigned errors = global.errors;
            Expression *eorig = ex;
            ex = ex->semantic(sc);
            if (errors < global.errors)
                e->error("%s cannot be resolved", eorig->toChars());

            /* Create tuple of functions of ex
             */
            //ex->print();
            Expressions *exps = new Expressions();
            FuncDeclaration *f;
            if (ex->op == TOKvar)
            {
                VarExp *ve = (VarExp *)ex;
                f = ve->var->isFuncDeclaration();
                ex = NULL;
            }
            else if (ex->op == TOKdotvar)
            {
                DotVarExp *dve = (DotVarExp *)ex;
                f = dve->var->isFuncDeclaration();
                if (dve->e1->op == TOKdottype || dve->e1->op == TOKthis)
                    ex = NULL;
                else
                    ex = dve->e1;
            }
            else
                f = NULL;
            Ptrait p;
            p.exps = exps;
            p.e1 = ex;
            p.ident = e->ident;
            overloadApply(f, &p, &fptraits);

            TupleExp *tup = new TupleExp(e->loc, exps);
            return tup->semantic(sc);
        }
        else
            assert(0);
    }
    else if (e->ident == Id::classInstanceSize)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        ClassDeclaration *cd;
        if (!s || (cd = s->isClassDeclaration()) == NULL)
        {
            e->error("first argument is not a class");
            goto Lfalse;
        }
        if (cd->sizeok == SIZEOKnone)
        {
            if (cd->scope)
                cd->semantic(cd->scope);
        }
        if (cd->sizeok != SIZEOKdone)
        {
            e->error("%s %s is forward referenced", cd->kind(), cd->toChars());
            goto Lfalse;
        }
        return new IntegerExp(e->loc, cd->structsize, Type::tsize_t);
    }
    else if (e->ident == Id::getAliasThis)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        AggregateDeclaration *ad;
        if (!s || (ad = s->isAggregateDeclaration()) == NULL)
        {
            e->error("argument is not an aggregate type");
            goto Lfalse;
        }

        Expressions *exps = new Expressions();
        if (ad->aliasthis)
            exps->push(new StringExp(e->loc, ad->aliasthis->ident->toChars()));

        Expression *ex = new TupleExp(e->loc, exps);
        ex = ex->semantic(sc);
        return ex;
    }
    else if (e->ident == Id::getAttributes)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        if (!s)
        {
        #if 0
            Expression *x = isExpression(o);
            Type *t = isType(o);
            if (x) printf("e = %s %s\n", Token::toChars(x->op), x->toChars());
            if (t) printf("t = %d %s\n", t->ty, t->toChars());
        #endif
            e->error("first argument is not a symbol");
            goto Lfalse;
        }
        //printf("getAttributes %s, attrs = %p, scope = %p\n", s->toChars(), s->userAttributes, s->userAttributesScope);
        UserAttributeDeclaration *udad = s->userAttribDecl;
        TupleExp *tup = new TupleExp(e->loc, udad ? udad->getAttributes() : new Expressions());
        return tup->semantic(sc);
    }
    else if (e->ident == Id::getFunctionAttributes)
    {
        /// extract all function attributes as a tuple (const/shared/inout/pure/nothrow/etc) except UDAs.

        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        Type *t = isType(o);
        TypeFunction *tf = NULL;

        if (s)
        {
            if (FuncDeclaration *f = s->isFuncDeclaration())
                t = f->type;
            else if (VarDeclaration *v = s->isVarDeclaration())
                t = v->type;
        }
        if (t)
        {
            if (t->ty == Tfunction)
                tf = (TypeFunction *)t;
            else if (t->ty == Tdelegate)
                tf = (TypeFunction *)t->nextOf();
            else if (t->ty == Tpointer && t->nextOf()->ty == Tfunction)
                tf = (TypeFunction *)t->nextOf();
        }
        if (!tf)
        {
            e->error("first argument is not a function");
            goto Lfalse;
        }

        Expressions *mods = new Expressions();

        PushAttributes pa;
        pa.mods = mods;

        tf->modifiersApply(&pa, &PushAttributes::fp);
        tf->attributesApply(&pa, &PushAttributes::fp, TRUSTformatSystem);

        TupleExp *tup = new TupleExp(e->loc, mods);
        return tup->semantic(sc);
    }
    else if (e->ident == Id::allMembers || e->ident == Id::derivedMembers)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        ScopeDsymbol *sds;
        if (!s)
        {
            e->error("argument has no members");
            goto Lfalse;
        }
        Import *import;
        if ((import = s->isImport()) != NULL)
        {
            // Bugzilla 9692
            sds = import->mod;
        }
        else if ((sds = s->isScopeDsymbol()) == NULL)
        {
            e->error("%s %s has no members", s->kind(), s->toChars());
            goto Lfalse;
        }

        // use a struct as local function
        struct PushIdentsDg
        {
            static int dg(void *ctx, size_t n, Dsymbol *sm)
            {
                if (!sm)
                    return 1;
                //printf("\t[%i] %s %s\n", i, sm->kind(), sm->toChars());
                if (sm->ident)
                {
                    if (sm->ident != Id::ctor &&
                        sm->ident != Id::dtor &&
                        sm->ident != Id::_postblit &&
                        memcmp(sm->ident->string, "__", 2) == 0)
                    {
                        return 0;
                    }

                    //printf("\t%s\n", sm->ident->toChars());
                    Identifiers *idents = (Identifiers *)ctx;

                    /* Skip if already present in idents[]
                     */
                    for (size_t j = 0; j < idents->dim; j++)
                    {   Identifier *id = (*idents)[j];
                        if (id == sm->ident)
                            return 0;
#ifdef DEBUG
                        // Avoid using strcmp in the first place due to the performance impact in an O(N^2) loop.
                        assert(strcmp(id->toChars(), sm->ident->toChars()) != 0);
#endif
                    }

                    idents->push(sm->ident);
                }
                else
                {
                    EnumDeclaration *ed = sm->isEnumDeclaration();
                    if (ed)
                    {
                        ScopeDsymbol::foreach(NULL, ed->members, &PushIdentsDg::dg, (Identifiers *)ctx);
                    }
                }
                return 0;
            }
        };

        Identifiers *idents = new Identifiers;

        ScopeDsymbol::foreach(sc, sds->members, &PushIdentsDg::dg, idents);

        ClassDeclaration *cd = sds->isClassDeclaration();
        if (cd && e->ident == Id::allMembers)
        {
            struct PushBaseMembers
            {
                static void dg(ClassDeclaration *cd, Identifiers *idents)
                {
                    for (size_t i = 0; i < cd->baseclasses->dim; i++)
                    {
                        ClassDeclaration *cb = (*cd->baseclasses)[i]->base;
                        ScopeDsymbol::foreach(NULL, cb->members, &PushIdentsDg::dg, idents);
                        if (cb->baseclasses->dim)
                            dg(cb, idents);
                    }
                }
            };
            PushBaseMembers::dg(cd, idents);
        }

        // Turn Identifiers into StringExps reusing the allocated array
        assert(sizeof(Expressions) == sizeof(Identifiers));
        Expressions *exps = (Expressions *)idents;
        for (size_t i = 0; i < idents->dim; i++)
        {
            Identifier *id = (*idents)[i];
            StringExp *se = new StringExp(e->loc, id->toChars());
            (*exps)[i] = se;
        }

        /* Making this a tuple is more flexible, as it can be statically unrolled.
         * To make an array literal, enclose __traits in [ ]:
         *   [ __traits(allMembers, ...) ]
         */
        Expression *ex = new TupleExp(e->loc, exps);
        ex = ex->semantic(sc);
        return ex;
    }
    else if (e->ident == Id::compiles)
    {
        /* Determine if all the objects - types, expressions, or symbols -
         * compile without error
         */
        if (!dim)
            goto Lfalse;

        for (size_t i = 0; i < dim; i++)
        {
            unsigned errors = global.startGagging();
            unsigned oldspec = global.speculativeGag;
            global.speculativeGag = global.gag;
            Scope *sc2 = sc->push();
            sc2->speculative = true;
            sc2->flags = sc->flags & ~SCOPEctfe | SCOPEcompile;
            bool err = false;

            RootObject *o = (*e->args)[i];
            Type *t = isType(o);
            Expression *ex = t ? t->toExpression() : isExpression(o);
            if (!ex && t)
            {
                Dsymbol *s;
                t->resolve(e->loc, sc2, &ex, &t, &s);
                if (t)
                {
                    t->semantic(e->loc, sc2);
                    if (t->ty == Terror)
                        err = true;
                }
                else if (s && s->errors)
                    err = true;
            }
            if (ex)
            {
                ex = ex->semantic(sc2);
                ex = resolvePropertiesOnly(sc2, ex);
                ex = ex->optimize(WANTvalue);
                ex = checkGC(sc2, ex);
                if (ex->op == TOKerror)
                    err = true;
            }

            sc2->pop();
            global.speculativeGag = oldspec;
            if (global.endGagging(errors) || err)
            {
                goto Lfalse;
            }
        }
        goto Ltrue;
    }
    else if (e->ident == Id::isSame)
    {
        /* Determine if two symbols are the same
         */
        if (dim != 2)
            goto Ldimerror;
        if (!TemplateInstance::semanticTiargs(e->loc, sc, e->args, 0))
            return new ErrorExp();
        RootObject *o1 = (*e->args)[0];
        RootObject *o2 = (*e->args)[1];
        Dsymbol *s1 = getDsymbol(o1);
        Dsymbol *s2 = getDsymbol(o2);

        //printf("isSame: %s, %s\n", o1->toChars(), o2->toChars());
#if 0
        printf("o1: %p\n", o1);
        printf("o2: %p\n", o2);
        if (!s1)
        {
            Expression *ea = isExpression(o1);
            if (ea)
                printf("%s\n", ea->toChars());
            Type *ta = isType(o1);
            if (ta)
                printf("%s\n", ta->toChars());
            goto Lfalse;
        }
        else
            printf("%s %s\n", s1->kind(), s1->toChars());
#endif
        if (!s1 && !s2)
        {
            Expression *ea1 = isExpression(o1);
            Expression *ea2 = isExpression(o2);
            if (ea1 && ea2)
            {
                if (ea1->equals(ea2))
                    goto Ltrue;
            }
        }

        if (!s1 || !s2)
            goto Lfalse;

        s1 = s1->toAlias();
        s2 = s2->toAlias();

        if (s1->isFuncAliasDeclaration())
            s1 = ((FuncAliasDeclaration *)s1)->toAliasFunc();
        if (s2->isFuncAliasDeclaration())
            s2 = ((FuncAliasDeclaration *)s2)->toAliasFunc();

        if (s1 == s2)
            goto Ltrue;
        else
            goto Lfalse;
    }
    else if (e->ident == Id::getUnitTests)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        if (!s)
        {
            e->error("argument %s to __traits(getUnitTests) must be a module or aggregate", o->toChars());
            goto Lfalse;
        }

        Import *imp = s->isImport();
        if (imp)  // Bugzilla 10990
            s = imp->mod;

        ScopeDsymbol* scope = s->isScopeDsymbol();

        if (!scope)
        {
            e->error("argument %s to __traits(getUnitTests) must be a module or aggregate, not a %s", s->toChars(), s->kind());
            goto Lfalse;
        }

        Expressions* unitTests = new Expressions();
        Dsymbols* symbols = scope->members;

        if (global.params.useUnitTests && symbols)
        {
            // Should actually be a set
            AA* uniqueUnitTests = NULL;
            collectUnitTests(symbols, uniqueUnitTests, unitTests);
        }

        TupleExp *tup = new TupleExp(e->loc, unitTests);
        return tup->semantic(sc);
    }
    else if(e->ident == Id::getVirtualIndex)
    {
        if (dim != 1)
            goto Ldimerror;
        RootObject *o = (*e->args)[0];
        Dsymbol *s = getDsymbol(o);
        FuncDeclaration *fd;
        if (!s || (fd = s->isFuncDeclaration()) == NULL)
        {
            e->error("first argument to __traits(getVirtualIndex) must be a function");
            goto Lfalse;
        }
        fd = fd->toAliasFunc(); // Neccessary to support multiple overloads.
        return new IntegerExp(e->loc, fd->vtblIndex, Type::tptrdiff_t);
    }
    else
    {
        if (const char *sub = (const char *)speller(e->ident->toChars(), &trait_search_fp, NULL, idchars))
            e->error("unrecognized trait '%s', did you mean '%s'?", e->ident->toChars(), sub);
        else
            e->error("unrecognized trait '%s'", e->ident->toChars());

        goto Lfalse;
    }

    return NULL;

Ldimerror:
    e->error("wrong number of arguments %d", (int)dim);
    goto Lfalse;


Lfalse:
    return new IntegerExp(e->loc, 0, Type::tbool);

Ltrue:
    return new IntegerExp(e->loc, 1, Type::tbool);
}
Example #6
0
File: module.c Project: dejlek/dmd
Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
{
    //printf("Module::load(ident = '%s')\n", ident->toChars());

    // Build module filename by turning:
    //  foo.bar.baz
    // into:
    //  foo\bar\baz
    char *filename = ident->toChars();
    if (packages && packages->dim)
    {
        OutBuffer buf;

        for (size_t i = 0; i < packages->dim; i++)
        {   Identifier *pid = (*packages)[i];

            buf.writestring(pid->toChars());
#if _WIN32
            buf.writeByte('\\');
#else
            buf.writeByte('/');
#endif
        }
        buf.writestring(filename);
        buf.writeByte(0);
        filename = (char *)buf.extractData();
    }

    Module *m = new Module(filename, ident, 0, 0);
    m->loc = loc;

    /* Look for the source file
     */
    const char *result = lookForSourceFile(filename);
    if (result)
        m->srcfile = new File(result);

    if (global.params.verbose)
    {
        fprintf(global.stdmsg, "import    ");
        if (packages)
        {
            for (size_t i = 0; i < packages->dim; i++)
            {
                Identifier *pid = (*packages)[i];
                fprintf(global.stdmsg, "%s.", pid->toChars());
            }
        }
        fprintf(global.stdmsg, "%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
    }

    if (!m->read(loc))
        return NULL;

    m->parse();

#ifdef IN_GCC
    d_gcc_magic_module(m);
#endif

    return m;
}
Example #7
0
static JSValue identifierToJSValue(VM& vm, const Identifier& identifier)
{
    if (identifier.isSymbol())
        return Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl()));
    return jsString(&vm, identifier.impl());
}
Example #8
0
void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s,
                    Pragma llvm_internal, const std::string &arg1str)
{
    if (llvm_internal == LLVMnone || llvm_internal == LLVMignore)
        return;

    if (s->llvmInternal)
    {
        error(Loc(), "multiple LDC specific pragmas not allowed not affect the same "
                     "declaration ('%s' at '%s')", s->toChars(), s->loc.toChars());
        fatal();
    }

    Identifier *ident = decl->ident;

    switch(llvm_internal)
    {
    case LLVMintrinsic:
        if (FuncDeclaration* fd = s->isFuncDeclaration())
        {
            fd->llvmInternal = llvm_internal;
            fd->intrinsicName = arg1str;
            fd->mangleOverride = strdup(fd->intrinsicName.c_str());
        }
        else if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            td->llvmInternal = llvm_internal;
            td->intrinsicName = arg1str;
        }
        else
        {
            error(s->loc, "the '%s' pragma is only allowed on function or template declarations",
                  ident->toChars());
            fatal();
        }
        break;

    case LLVMglobal_crt_ctor:
    case LLVMglobal_crt_dtor:
        if (FuncDeclaration* fd = s->isFuncDeclaration())
        {
            assert(fd->type->ty == Tfunction);
            TypeFunction* type = static_cast<TypeFunction*>(fd->type);
            Type* retType = type->next;
            if (retType->ty != Tvoid || type->parameters->dim > 0 || (
            fd->isAggregateMember()
                  && !fd->isStatic())) {
                error(s->loc, "the '%s' pragma is only allowed on void functions which take no arguments",
                      ident->toChars());
                fd->llvmInternal = LLVMnone;
                break;
            }

            fd->llvmInternal = llvm_internal;
            fd->priority = std::atoi(arg1str.c_str());
        }
        else
        {
            error(s->loc, "the '%s' pragma is only allowed on function declarations",
                  ident->toChars());
            s->llvmInternal = LLVMnone;
        }
        break;

    case LLVMatomic_rmw:
        if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            td->llvmInternal = llvm_internal;
            td->intrinsicName = arg1str;
        }
        else
        {
            error(s->loc, "the '%s' pragma is only allowed on template declarations",
                  ident->toChars());
            fatal();
        }
        break;

    case LLVMva_start:
    case LLVMva_arg:
    case LLVMatomic_load:
    case LLVMatomic_store:
    case LLVMatomic_cmp_xchg:
        if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            if (td->parameters->dim != 1)
            {
                error(s->loc, "the '%s' pragma template must have exactly one template parameter",
                      ident->toChars());
                fatal();
            }
            else if (!td->onemember)
            {
                error(s->loc, "the '%s' pragma template must have exactly one member",
                      ident->toChars());
                fatal();
            }
            else if (td->overnext || td->overroot)
            {
                error(s->loc, "the '%s' pragma template must not be overloaded",
                      ident->toChars());
                fatal();
            }
            td->llvmInternal = llvm_internal;
        }
        else
        {
            error(s->loc, "the '%s' pragma is only allowed on template declarations",
                  ident->toChars());
            fatal();
        }
        break;

    case LLVMva_copy:
    case LLVMva_end:
    case LLVMfence:
    case LLVMbitop_bt:
    case LLVMbitop_btc:
    case LLVMbitop_btr:
    case LLVMbitop_bts:
    case LLVMbitop_vld:
    case LLVMbitop_vst:
        if (FuncDeclaration* fd = s->isFuncDeclaration())
        {
            fd->llvmInternal = llvm_internal;
        }
        else
        {
            error(s->loc, "the '%s' pragma is only allowed on function declarations",
                  ident->toChars());
            fatal();
        }
        break;

    case LLVMno_typeinfo:
        s->llvmInternal = llvm_internal;
        break;

    case LLVMalloca:
        if (FuncDeclaration* fd = s->isFuncDeclaration())
        {
            fd->llvmInternal = llvm_internal;
        }
        else
        {
            error(s->loc, "the '%s' pragma must only be used on function declarations "
                  "of type 'void* function(uint nbytes)'", ident->toChars());
            fatal();
        }
        break;

    case LLVMinline_asm:
        if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            if (td->parameters->dim > 1)
            {
                error(s->loc, "the '%s' pragma template must have exactly zero or one "
                      "template parameters", ident->toChars());
                fatal();
            }
            else if (!td->onemember)
            {
                error(s->loc, "the '%s' pragma template must have exactly one member",
                      ident->toChars());
                fatal();
            }
            td->llvmInternal = llvm_internal;
        }
        else
        {
            error(s->loc, "the '%s' pragma is only allowed on template declarations",
                  ident->toChars());
            fatal();
        }
        break;

    case LLVMinline_ir:
        if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            Dsymbol* member = td->onemember;
            if (!member)
            {
                error(s->loc, "the '%s' pragma template must have exactly one member",
                      ident->toChars());
                fatal();
            }
            FuncDeclaration* fun = member->isFuncDeclaration();
            if (!fun)
            {
                error(s->loc, "the '%s' pragma template's member must be a function declaration",
                      ident->toChars());
                fatal();
            }

            TemplateParameters& params = *td->parameters;
            bool valid_params =
                params.dim == 3 && params[1]->isTemplateTypeParameter() &&
                params[2]->isTemplateTupleParameter();

            if(valid_params)
            {
                TemplateValueParameter* p0 = params[0]->isTemplateValueParameter();
                valid_params = valid_params && p0 && p0->valType == Type::tstring;
            }

            if(!valid_params)
            {
                error(s->loc, "the '%s' pragma template must have exactly three parameters: "
                      "a string, a type and a type tuple", ident->toChars());
                fatal();
            }

            td->llvmInternal = llvm_internal;
        }
        else
        {
            error(s->loc, "the '%s' pragma is only allowed on template declarations",
                  ident->toChars());
            fatal();
        }
        break;

    case LLVMextern_weak:
        if (VarDeclaration* vd = s->isVarDeclaration())
        {
            if (!vd->isDataseg() || !(vd->storage_class & STCextern)) {
                error(s->loc, "'%s' requires storage class 'extern'",
                    ident->toChars());
                fatal();
            }

            // It seems like the interaction between weak symbols and thread-local
            // storage is not well-defined (the address of an undefined weak TLS
            // symbol is non-zero on the ELF static TLS model on Linux x86_64).
            // Thus, just disallow this altogether.
            if (vd->isThreadlocal()) {
                error(s->loc, "'%s' cannot be applied to thread-local variable '%s'",
                    ident->toChars(), vd->toPrettyChars());
                fatal();
            }
            vd->llvmInternal = llvm_internal;
        }
        else
        {
            // Currently, things like "pragma(LDC_extern_weak) extern int foo;"
            // fail because 'extern' creates an intermediate
            // StorageClassDeclaration. This might eventually be fixed by making
            // extern_weak a proper storage class.
            error(s->loc, "the '%s' pragma can only be specified directly on "
                "variable declarations for now", ident->toChars());
            fatal();
        }
        break;

    default:
        warning(s->loc,
                "the LDC specific pragma '%s' is not yet implemented, ignoring",
                ident->toChars());
    }
}
Example #9
0
void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const Identifier& name)
{
    Base::finishCreation(exec->globalData());
    ASSERT(inherits(&s_info));
    m_executable.set(exec->globalData(), this, executable);
    putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
    putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
Example #10
0
void Converter::RenameIdent(Identifier& ident)
{
    ident.AppendPrefix(nameMangling_.temporaryPrefix);
}
Example #11
0
Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
{   Module *m;
    char *filename;

    //printf("Module::load(ident = '%s')\n", ident->toChars());

    // Build module filename by turning:
    //  foo.bar.baz
    // into:
    //  foo\bar\baz
    filename = ident->toChars();
    if (packages && packages->dim)
    {
        OutBuffer buf;

        for (size_t i = 0; i < packages->dim; i++)
        {   Identifier *pid = packages->tdata()[i];

            buf.writestring(pid->toChars());
#if _WIN32
            buf.writeByte('\\');
#else
            buf.writeByte('/');
#endif
        }
        buf.writestring(filename);
        buf.writeByte(0);
        filename = (char *)buf.extractData();
    }

    m = new Module(filename, ident, 0, 0);
    m->loc = loc;

    /* Search along global.path for .di file, then .d file.
     */
    char *result = NULL;
    FileName *fdi = FileName::forceExt(filename, global.hdr_ext);
    FileName *fd  = FileName::forceExt(filename, global.mars_ext);
    char *sdi = fdi->toChars();
    char *sd  = fd->toChars();

    if (FileName::exists(sdi))
        result = sdi;
    else if (FileName::exists(sd))
        result = sd;
    else if (FileName::absolute(filename))
        ;
    else if (!global.path)
        ;
    else
    {
        for (size_t i = 0; i < global.path->dim; i++)
        {
            char *p = global.path->tdata()[i];
            char *n = FileName::combine(p, sdi);
            if (FileName::exists(n))
            {   result = n;
                break;
            }
            mem.free(n);
            n = FileName::combine(p, sd);
            if (FileName::exists(n))
            {   result = n;
                break;
            }
            mem.free(n);
        }
    }
    if (result)
        m->srcfile = new File(result);

    if (global.params.verbose)
    {
        printf("import    ");
        if (packages)
        {
            for (size_t i = 0; i < packages->dim; i++)
            {   Identifier *pid = packages->tdata()[i];
                printf("%s.", pid->toChars());
            }
        }
        printf("%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
    }

    m->read(loc);
    m->parse();

#ifdef IN_GCC
    d_gcc_magic_module(m);
#endif

    return m;
}
Example #12
0
void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s,
                    Pragma llvm_internal, const std::string &arg1str)
{
    if (llvm_internal == LLVMnone || llvm_internal == LLVMignore)
        return;

    if (s->llvmInternal)
    {
        error("multiple LDC specific pragmas not allowed not affect the same "
            "declaration ('%s' at '%s')", s->toChars(), s->loc.toChars());
        fatal();
    }

    Identifier *ident = decl->ident;

    switch(llvm_internal)
    {
    case LLVMintrinsic:
        if (FuncDeclaration* fd = s->isFuncDeclaration())
        {
            fd->llvmInternal = llvm_internal;
            fd->intrinsicName = arg1str;
            fd->linkage = LINKintrinsic;
            static_cast<TypeFunction*>(fd->type)->linkage = LINKintrinsic;
        }
        else if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            td->llvmInternal = llvm_internal;
            td->intrinsicName = arg1str;
        }
        else
        {
            error("only allowed on function declarations");
            fatal();
        }
        break;
    case LLVMglobal_crt_ctor:
    case LLVMglobal_crt_dtor:
        if (FuncDeclaration* fd = s->isFuncDeclaration())
        {
            assert(fd->type->ty == Tfunction);
            TypeFunction* type = static_cast<TypeFunction*>(fd->type);
            Type* retType = type->next;
            if (retType->ty != Tvoid || type->parameters->dim > 0 || (
#if DMDV2
            fd->isAggregateMember()
#else
            fd->isThis()
#endif
                  && !fd->isStatic())) {
                error(fd->loc, "the '%s' pragma is only allowed on void functions which take no arguments",
                      ident->toChars());
                fd->llvmInternal = LLVMnone;
                break;
            }

            fd->llvmInternal = llvm_internal;
            fd->priority = std::atoi(arg1str.c_str());
        }
        else
        {
            error(s->loc, "the '%s' pragma is only allowed on function declarations",
                  ident->toChars());
            s->llvmInternal = LLVMnone;
        }
        break;

    case LLVMatomic_rmw:
        if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            td->llvmInternal = llvm_internal;
            td->intrinsicName = arg1str;
        }
        else
        {
            error("the '%s' pragma is only allowed on template declarations",
                ident->toChars());
            fatal();
        }
        break;

    case LLVMva_start:
    case LLVMva_arg:
    case LLVMatomic_load:
    case LLVMatomic_store:
    case LLVMatomic_cmp_xchg:
        if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            if (td->parameters->dim != 1)
            {
                error("the '%s' pragma template must have exactly one template parameter",
                    ident->toChars());
                fatal();
            }
            else if (!td->onemember)
            {
                error("the '%s' pragma template must have exactly one member",
                    ident->toChars());
                fatal();
            }
            else if (td->overnext || td->overroot)
            {
                error("the '%s' pragma template must not be overloaded",
                    ident->toChars());
                fatal();
            }
            td->llvmInternal = llvm_internal;
        }
        else
        {
            error("the '%s' pragma is only allowed on template declarations",
                ident->toChars());
            fatal();
        }
        break;

    case LLVMva_copy:
    case LLVMva_end:
    case LLVMfence:
    case LLVMbitop_bt:
    case LLVMbitop_btc:
    case LLVMbitop_btr:
    case LLVMbitop_bts:
        if (FuncDeclaration* fd = s->isFuncDeclaration())
        {
            fd->llvmInternal = llvm_internal;
        }
        else
        {
            error("the '%s' pragma is only allowed on function declarations",
                ident->toChars());
            fatal();
        }
        break;

    case LLVMno_typeinfo:
        s->llvmInternal = llvm_internal;
        break;

    case LLVMalloca:
        if (FuncDeclaration* fd = s->isFuncDeclaration())
        {
            fd->llvmInternal = llvm_internal;
        }
        else
        {
            error("the '%s' pragma must only be used on function declarations "
                "of type 'void* function(uint nbytes)'", ident->toChars());
            fatal();
        }
        break;

    case LLVMinline_asm:
        if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            if (td->parameters->dim > 1)
            {
                error("the '%s' pragma template must have exactly zero or one "
                    "template parameters", ident->toChars());
                fatal();
            }
            else if (!td->onemember)
            {
                error("the '%s' pragma template must have exactly one member",
                    ident->toChars());
                fatal();
            }
            td->llvmInternal = llvm_internal;
        }
        else
        {
            error("the '%s' pragma is only allowed on template declarations",
                ident->toChars());
            fatal();
        }
        break;

    case LLVMinline_ir:
        if (TemplateDeclaration* td = s->isTemplateDeclaration())
        {
            Dsymbol* member = td->onemember;
            if (!member)
            {
                error("the '%s' pragma template must have exactly one member",
                    ident->toChars());
                fatal();
            }
            FuncDeclaration* fun = member->isFuncDeclaration();
            if (!fun)
            {
                error("the '%s' pragma template's member must be a function declaration",
                    ident->toChars());
                fatal();
            }

            TemplateParameters& params = *td->parameters;
            bool valid_params =
                params.dim == 3 && params[1]->isTemplateTypeParameter() &&
                params[2]->isTemplateTupleParameter();

            if(valid_params)
            {
                TemplateValueParameter* p0 = params[0]->isTemplateValueParameter();
                valid_params = valid_params && p0 && p0->valType == Type::tstring;
            }

            if(!valid_params)
            {
                error("the '%s' pragma template must have exactly three parameters: "
                    "a string, a type and a type tuple", ident->toChars());
                fatal();
            }

            td->llvmInternal = llvm_internal;
        }
        else
        {
            error("the '%s' pragma is only allowed on template declarations",
                ident->toChars());
            fatal();
        }
        break;

    default:
        warning(Loc(),
            "the LDC specific pragma '%s' is not yet implemented, ignoring",
            ident->toChars());
    }
}
Example #13
0
InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<Structure> structure, const Identifier& name)
    : JSObject(structure)
{
    putDirect(globalData->propertyNames->name, jsString(globalData, name.ustring()), DontDelete | ReadOnly | DontEnum);
}
Example #14
0
File: init.c Project: smunix/ldc
/***************************************
 * This works by transforming a struct initializer into
 * a struct literal. In the future, the two should be the
 * same thing.
 */
Expression *StructInitializer::toExpression()
{   Expression *e;
    size_t offset;

    //printf("StructInitializer::toExpression() %s\n", toChars());
    if (!ad)                            // if fwd referenced
    {
        return NULL;
    }
    StructDeclaration *sd = ad->isStructDeclaration();
    if (!sd)
        return NULL;
    Expressions *elements = new Expressions();
    size_t nfields = ad->fields.dim;
#if DMDV2
    if (sd->isnested)
       nfields--;
#endif
    elements->setDim(nfields);
    for (size_t i = 0; i < elements->dim; i++)
    {
        elements->tdata()[i] = NULL;
    }
    unsigned fieldi = 0;
    for (size_t i = 0; i < value.dim; i++)
    {
        Identifier *id = field.tdata()[i];
        if (id)
        {
            Dsymbol * s = ad->search(loc, id, 0);
            if (!s)
            {
                error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars());
                goto Lno;
            }

            // Find out which field index it is
            for (fieldi = 0; 1; fieldi++)
            {
                if (fieldi >= nfields)
                {
                    s->error("is not a per-instance initializable field");
                    goto Lno;
                }
                if (s == ad->fields.tdata()[fieldi])
                    break;
            }
        }
        else if (fieldi >= nfields)
        {   error(loc, "too many initializers for '%s'", ad->toChars());
            goto Lno;
        }
        Initializer *iz = value.tdata()[i];
        if (!iz)
            goto Lno;
        Expression *ex = iz->toExpression();
        if (!ex)
            goto Lno;
        if (elements->tdata()[fieldi])
        {   error(loc, "duplicate initializer for field '%s'",
                ad->fields.tdata()[fieldi]->toChars());
            goto Lno;
        }
        elements->tdata()[fieldi] = ex;
        ++fieldi;
    }
    // Now, fill in any missing elements with default initializers.
    // We also need to validate any anonymous unions
    offset = 0;
    for (size_t i = 0; i < elements->dim; )
    {
        VarDeclaration * vd = ad->fields.tdata()[i]->isVarDeclaration();

        //printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset);
        if (vd->offset < offset)
        {
            // Only the first field of a union can have an initializer
            if (elements->tdata()[i])
                goto Lno;
        }
        else
        {
            if (!elements->tdata()[i])
                // Default initialize
                elements->tdata()[i] = vd->type->defaultInit();
        }
        offset = vd->offset + vd->type->size();
        i++;
#if 0
        int unionSize = ad->numFieldsInUnion(i);
        if (unionSize == 1)
        {   // Not a union -- default initialize if missing
            if (!elements->tdata()[i])
                elements->tdata()[i] = vd->type->defaultInit();
        }
        else
        {   // anonymous union -- check for errors
            int found = -1; // index of the first field with an initializer
            for (int j = i; j < i + unionSize; ++j)
            {
                if (!elements->tdata()[j])
                    continue;
                if (found >= 0)
                {
                    VarDeclaration * v1 = ((Dsymbol *)ad->fields.data[found])->isVarDeclaration();
                    VarDeclaration * v = ((Dsymbol *)ad->fields.data[j])->isVarDeclaration();
                    error(loc, "%s cannot have initializers for fields %s and %s in same union",
                        ad->toChars(),
                        v1->toChars(), v->toChars());
                    goto Lno;
                }
                found = j;
            }
            if (found == -1)
            {
                error(loc, "no initializer for union that contains field %s",
                    vd->toChars());
                goto Lno;
            }
        }
        i += unionSize;
#endif
    }
    e = new StructLiteralExp(loc, sd, elements);
    e->type = sd->type;
    return e;

Lno:
    delete elements;
    return NULL;
}
Example #15
0
/// Parse a function definition signature.
///   func-signature:
///     func-arguments func-throws? func-signature-result?
///   func-signature-result:
///     '->' type
///
/// Note that this leaves retType as null if unspecified.
ParserStatus
Parser::parseFunctionSignature(Identifier SimpleName,
                               DeclName &FullName,
                               SmallVectorImpl<ParameterList*> &bodyParams,
                               DefaultArgumentInfo &defaultArgs,
                               SourceLoc &throwsLoc,
                               bool &rethrows,
                               TypeRepr *&retType) {
  SmallVector<Identifier, 4> NamePieces;
  NamePieces.push_back(SimpleName);
  FullName = SimpleName;
  
  ParserStatus Status;
  // We force first type of a func declaration to be a tuple for consistency.
  if (Tok.is(tok::l_paren)) {
    ParameterContextKind paramContext;
    if (SimpleName.isOperator())
      paramContext = ParameterContextKind::Operator;
    else
      paramContext = ParameterContextKind::Function;

    Status = parseFunctionArguments(NamePieces, bodyParams, paramContext,
                                    defaultArgs);
    FullName = DeclName(Context, SimpleName, 
                        llvm::makeArrayRef(NamePieces.begin() + 1,
                                           NamePieces.end()));

    if (bodyParams.empty()) {
      // If we didn't get anything, add a () pattern to avoid breaking
      // invariants.
      assert(Status.hasCodeCompletion() || Status.isError());
      bodyParams.push_back(ParameterList::createEmpty(Context));
    }
  } else {
    diagnose(Tok, diag::func_decl_without_paren);
    Status = makeParserError();

    // Recover by creating a '() -> ?' signature.
    bodyParams.push_back(ParameterList::createEmpty(Context, PreviousLoc,
                                                    PreviousLoc));
    FullName = DeclName(Context, SimpleName, bodyParams.back());
  }
  
  // Check for the 'throws' keyword.
  rethrows = false;
  if (Tok.is(tok::kw_throws)) {
    throwsLoc = consumeToken();
  } else if (Tok.is(tok::kw_rethrows)) {
    throwsLoc = consumeToken();
    rethrows = true;
  } else if (Tok.is(tok::kw_throw)) {
    throwsLoc = consumeToken();
    diagnose(throwsLoc, diag::throw_in_function_type)
      .fixItReplace(throwsLoc, "throws");
  }

  SourceLoc arrowLoc;
  // If there's a trailing arrow, parse the rest as the result type.
  if (Tok.isAny(tok::arrow, tok::colon)) {
    if (!consumeIf(tok::arrow, arrowLoc)) {
      // FixIt ':' to '->'.
      diagnose(Tok, diag::func_decl_expected_arrow)
          .fixItReplace(SourceRange(Tok.getLoc()), "->");
      arrowLoc = consumeToken(tok::colon);
    }

    ParserResult<TypeRepr> ResultType =
      parseType(diag::expected_type_function_result);
    if (ResultType.hasCodeCompletion())
      return ResultType;
    retType = ResultType.getPtrOrNull();
    if (!retType) {
      Status.setIsParseError();
      return Status;
    }
  } else {
    // Otherwise, we leave retType null.
    retType = nullptr;
  }

  // Check for 'throws' and 'rethrows' after the type and correct it.
  if (!throwsLoc.isValid()) {
    if (Tok.is(tok::kw_throws)) {
      throwsLoc = consumeToken();
    } else if (Tok.is(tok::kw_rethrows)) {
      throwsLoc = consumeToken();
      rethrows = true;
    }

    if (throwsLoc.isValid()) {
      assert(arrowLoc.isValid());
      assert(retType);
      auto diag = rethrows ? diag::rethrows_after_function_result
                           : diag::throws_after_function_result;
      SourceLoc typeEndLoc = Lexer::getLocForEndOfToken(SourceMgr,
                                                        retType->getEndLoc());
      SourceLoc throwsEndLoc = Lexer::getLocForEndOfToken(SourceMgr, throwsLoc);
      diagnose(Tok, diag)
        .fixItInsert(arrowLoc, rethrows ? "rethrows " : "throws ")
        .fixItRemoveChars(typeEndLoc, throwsEndLoc);
    }
  }

  return Status;
}
Example #16
0
		bool operator<(const KeywordBase& other) const
		{ return identifier__.compare(other.identifier__) < 0; }
Example #17
0
void InternalFunction::finishCreation(JSGlobalData& globalData, const Identifier& name)
{
    Base::finishCreation(globalData);
    ASSERT(inherits(&s_info));
    putDirect(globalData, globalData.propertyNames->name, jsString(&globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
}
// UDD = user defined domain
// AGD = auto generated domain (those starting with RDB$)
bool FieldPropertiesDialog::getStatementsToExecute(wxString& statements,
    bool justCheck)
{
    wxString colNameSql(Identifier::userString(textctrl_fieldname->GetValue()));
    Identifier selDomain(choice_domain->GetStringSelection());
    bool newDomain = getIsNewDomainSelected();
    wxString selDatatype = choice_datatype->GetStringSelection();
    wxString dtSize = textctrl_size->GetValue();
    wxString dtScale = textctrl_scale->GetValue();
    bool isNullable = !checkbox_notnull->IsChecked();

    int n = choice_datatype->GetSelection();
    if (n >= 0 && n < datatypescnt)
    {
        if (!datatypes[n].hasSize)
            dtSize.Clear();
        if (!datatypes[n].hasScale)
            dtScale.Clear();
    }

    wxString alterTable = "ALTER TABLE " + tableM->getQuotedName() + " ";
    enum unn { unnNone, unnBefore, unnAfter } update_not_null = unnNone;

    // detect changes to existing field, create appropriate SQL actions
    if (columnM)
    {
        // field name changed ?
        // compare regardless of active quoting rules, so that name
        // will remain unchanged if edit field contents haven't changed
        // OR if the altered name would result in same SQL identifier
        if (textctrl_fieldname->GetValue() == columnM->getName_()
            || colNameSql == columnM->getQuotedName())
        {
            // no changes -> use original name for all other statements
            colNameSql = columnM->getQuotedName();
        }
        else
        {
            statements += alterTable + "ALTER " + columnM->getQuotedName()
                + " TO " + colNameSql + ";\n\n";
        }

        // domain changed ?
        wxString type, size, scale, charset;
        if (!getDomainInfo(columnM->getSource(), type, size, scale, charset))
        {
            ::wxMessageBox(_("Can not get domain info - aborting."),
                _("Error"), wxOK | wxICON_ERROR);
            return false;
        }
        if (columnM->getSource() != selDomain.get() && !newDomain)
        {   // UDD -> other UDD  or  AGD -> UDD
            statements += alterTable + "ALTER " + colNameSql +
                " TYPE " + selDomain.getQuoted() + ";\n\n";
        }
        else if (newDomain
            || type.CmpNoCase(selDatatype) || size != dtSize || scale != dtScale)
        {   // UDD -> AGD  or  AGD -> different AGD
            statements += alterTable + "ALTER " + colNameSql +
                " TYPE ";
            statements += selDatatype;
            if (!dtSize.IsEmpty())
            {
                statements += "(" + dtSize;
                if (!dtScale.IsEmpty())
                    statements += "," + dtScale;
                statements += ")";
            }
            statements += ";\n\n";
        }

        // not null option changed ?
        if (isNullable != columnM->isNullable(CheckDomainNullability))
        {
            if (!isNullable) // change from NULL to NOT NULL
                update_not_null = unnBefore;

            statements += "UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = ";
            if (isNullable)
                statements += "NULL";
            else
                statements += "1";
            // direct change in RDB$RELATION_FIELDS needs unquoted field name
            Identifier id;
            id.setFromSql(colNameSql);
            wxString fnm = id.get();
            fnm.Replace("'", "''");
            wxString tnm = tableM->getName_();
            statements += "\nWHERE RDB$FIELD_NAME = '" + fnm
                + "' AND RDB$RELATION_NAME = '" + tnm
                + "';\n\n";

            if (isNullable) // change from NOT NULL to NULL
            {
                wxString constraintName;
                if (getNotNullConstraintName(fnm, constraintName))
                {
                    statements += alterTable + "DROP CONSTRAINT "
                        + constraintName + ";\n\n";
                }
            }
        }
    }
    else // create new field
    {
        wxString addCollate;
        statements += alterTable + "ADD \n" + colNameSql + " ";
        if (newDomain)
        {
            statements += selDatatype;
            if (!dtSize.IsEmpty())
            {
                statements += "(" + dtSize;
                if (!dtScale.IsEmpty())
                    statements += "," + dtScale;
                statements += ")";
            }
            if (datatypes[n].isChar)
            {
                wxString charset = choice_charset->GetStringSelection();
                wxString collate = choice_collate->GetStringSelection();
                if (!charset.IsEmpty())
                {
                    statements += " CHARACTER SET " + charset;
                    if (!collate.IsEmpty())
                        addCollate = " COLLATE " + collate;
                }
            }
        }
        else
            statements += selDomain.getQuoted();

        if (!isNullable)
        {
            statements += " NOT NULL";
            update_not_null = unnAfter;
        }
        statements += addCollate + ";\n\n";
    }

    if (update_not_null != unnNone && !justCheck)
    {
        wxString s = ::wxGetTextFromUser(
            _("Enter value for existing fields containing NULL"),
            _("Update Existing NULL Values"), "", this);
        if (update_not_null == unnBefore)
        {
            wxString origColumnName = columnM->getQuotedName();
            statements = "UPDATE " + tableM->getQuotedName()
                + " \nSET " + origColumnName + " = '" + s
                + "' \nWHERE " + origColumnName + " IS NULL;\n"
                + statements;
        }
        else
        {
            statements = statements + "COMMIT;\n"
                + "UPDATE " + tableM->getQuotedName()
                + " \nSET " + colNameSql + " = '" + s
                + "' \nWHERE " + colNameSql + " IS NULL;\n";
        }
    }
    statements += textctrl_sql->GetValue();
    return !statements.IsEmpty();
}
Example #19
0
File: import.c Project: Rayerd/dmd
void Import::semantic(Scope *sc)
{
    //printf("Import::semantic('%s')\n", toChars());

    // Load if not already done so
    if (!mod)
    {   load(sc);
        mod->importAll(0);
    }

    if (mod)
    {
#if 0
        if (mod->loc.linnum != 0)
        {   /* If the line number is not 0, then this is not
             * a 'root' module, i.e. it was not specified on the command line.
             */
            mod->importedFrom = sc->module->importedFrom;
            assert(mod->importedFrom);
        }
#endif

        // Modules need a list of each imported module
        //printf("%s imports %s\n", sc->module->toChars(), mod->toChars());
        sc->module->aimports.push(mod);

        if (!isstatic && !aliasId && !names.dim)
        {
            /* Default to private importing
             */
            enum PROT prot = sc->protection;
            if (!sc->explicitProtection)
                prot = PROTprivate;
            for (Scope *scd = sc; scd; scd = scd->enclosing)
            {
                if (scd->scopesym)
                {
                    scd->scopesym->importScope(mod, prot);
                    break;
                }
            }
        }

        mod->semantic();

        if (mod->needmoduleinfo)
        {   //printf("module4 %s because of %s\n", sc->module->toChars(), mod->toChars());
            sc->module->needmoduleinfo = 1;
        }

        sc = sc->push(mod);
        for (size_t i = 0; i < aliasdecls.dim; i++)
        {   Dsymbol *s = aliasdecls.tdata()[i];

            //printf("\tImport alias semantic('%s')\n", s->toChars());
            if (!mod->search(loc, names.tdata()[i], 0))
                error("%s not found", (names.tdata()[i])->toChars());

            s->semantic(sc);
        }
        sc = sc->pop();
    }

    if (global.params.moduleDeps != NULL)
    {
        /* The grammar of the file is:
         *      ImportDeclaration
         *          ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
         *      ModuleAliasIdentifier ] "\n"
         *
         *      BasicImportDeclaration
         *          ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection
         *              " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
         *
         *      FilePath
         *          - any string with '(', ')' and '\' escaped with the '\' character
         */

        OutBuffer *ob = global.params.moduleDeps;

        ob->writestring(sc->module->toPrettyChars());
        ob->writestring(" (");
        escapePath(ob, sc->module->srcfile->toChars());
        ob->writestring(") : ");

        ProtDeclaration::protectionToCBuffer(ob, sc->protection);
        if (isstatic)
            StorageClassDeclaration::stcToCBuffer(ob, STCstatic);
        ob->writestring(": ");

        if (packages)
        {
            for (size_t i = 0; i < packages->dim; i++)
            {
                Identifier *pid = packages->tdata()[i];
                ob->printf("%s.", pid->toChars());
            }
        }

        ob->writestring(id->toChars());
        ob->writestring(" (");
        if (mod)
            escapePath(ob, mod->srcfile->toChars());
        else
            ob->writestring("???");
        ob->writebyte(')');

        for (size_t i = 0; i < names.dim; i++)
        {
            if (i == 0)
                ob->writebyte(':');
            else
                ob->writebyte(',');

            Identifier *name = names.tdata()[i];
            Identifier *alias = aliases.tdata()[i];

            if (!alias)
            {
                ob->printf("%s", name->toChars());
                alias = name;
            }
            else
                ob->printf("%s=%s", alias->toChars(), name->toChars());
        }

        if (aliasId)
            ob->printf(" -> %s", aliasId->toChars());

        ob->writenl();
    }

    //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
}
Example #20
0
File: clone.c Project: 1100110/dmd
FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc)
{
    if (!needOpEquals())
        return NULL;        // bitwise comparison would work

    //printf("StructDeclaration::buildXopEquals() %s\n", toChars());
    if (Dsymbol *eq = search_function(this, Id::eq))
    {
        if (FuncDeclaration *fd = eq->isFuncDeclaration())
        {
            TypeFunction *tfeqptr;
            {
                Scope sc;

                /* const bool opEquals(ref const S s);
                 */
                Parameters *parameters = new Parameters;
                parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL));
                tfeqptr = new TypeFunction(parameters, Type::tbool, 0, LINKd);
                tfeqptr->mod = MODconst;
                tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), &sc);
            }
            fd = fd->overloadExactMatch(tfeqptr);
            if (fd)
                return fd;
        }
    }

    if (!xerreq)
    {
        Identifier *id = Lexer::idPool("_xopEquals");
        Expression *e = new IdentifierExp(loc, Id::empty);
        e = new DotIdExp(loc, e, Id::object);
        e = new DotIdExp(loc, e, id);
        e = e->semantic(sc);
        Dsymbol *s = getDsymbol(e);
        if (!s)
        {
            ::error(Loc(), "ICE: %s not found in object module. You must update druntime", id->toChars());
            fatal();
        }
        assert(s);
        xerreq = s->isFuncDeclaration();
    }

    Loc declLoc = Loc();    // loc is unnecessary so __xopEquals is never called directly
    Loc loc = Loc();        // loc is unnecessary so errors are gagged

    Parameters *parameters = new Parameters;
    parameters->push(new Parameter(STCref | STCconst, type, Id::p, NULL));
    parameters->push(new Parameter(STCref | STCconst, type, Id::q, NULL));
    TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd);
    tf = (TypeFunction *)tf->semantic(loc, sc);

    Identifier *id = Lexer::idPool("__xopEquals");
    FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);

    Expression *e1 = new IdentifierExp(loc, Id::p);
    Expression *e2 = new IdentifierExp(loc, Id::q);
    Expression *e = new EqualExp(TOKequal, loc, e1, e2);

    fop->fbody = new ReturnStatement(loc, e);

    unsigned errors = global.startGagging();    // Do not report errors
    Scope *sc2 = sc->push();
    sc2->stc = 0;
    sc2->linkage = LINKd;

    fop->semantic(sc2);
    fop->semantic2(sc2);

    sc2->pop();
    if (global.endGagging(errors))    // if errors happened
        fop = xerreq;

    return fop;
}
bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    // When accessing a Window cross-domain, functions are always the native built-in ones, and they
    // are not affected by properties changed on the Window or anything in its prototype chain.
    // This is consistent with the behavior of Firefox.

    const HashEntry* entry;

    // We don't want any properties other than "close" and "closed" on a closed window.
    if (!impl()->frame()) {
        // The following code is safe for cross-domain and same domain use.
        // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype).
        entry = s_info.propHashTable(exec)->entry(exec, propertyName);
        if (entry && !(entry->attributes() & Function) && entry->propertyGetter() == jsDOMWindowClosed) {
            slot.setCustom(this, entry->propertyGetter());
            return true;
        }
        entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
        if (entry && (entry->attributes() & Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) {
            slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
            return true;
        }

        // FIXME: We should have a message here that explains why the property access/function call was
        // not allowed. 
        slot.setUndefined();
        return true;
    }

    // We need to check for cross-domain access here without printing the generic warning message
    // because we always allow access to some function, just different ones depending whether access
    // is allowed.
    String errorMessage;
    bool allowsAccess = allowsAccessFrom(exec, errorMessage);

    // Look for overrides before looking at any of our own properties, but ignore overrides completely
    // if this is cross-domain access.
    if (allowsAccess && JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot))
        return true;

    // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the
    // prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot.
    // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of
    // what prototype is actually set on this object.
    entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
    if (entry) {
        if (entry->attributes() & Function) {
            if (entry->function() == jsDOMWindowPrototypeFunctionBlur) {
                if (!allowsAccess) {
                    slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>);
                    return true;
                }
            } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) {
                if (!allowsAccess) {
                    slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
                    return true;
                }
            } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) {
                if (!allowsAccess) {
                    slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>);
                    return true;
                }
            } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) {
                if (!allowsAccess) {
                    slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>);
                    return true;
                }
            } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) {
                if (!DOMWindow::canShowModalDialog(impl()->frame())) {
                    slot.setUndefined();
                    return true;
                }
            }
        }
    } else {
        // Allow access to toString() cross-domain, but always Object.prototype.toString.
        if (propertyName == exec->propertyNames().toString) {
            if (!allowsAccess) {
                slot.setCustom(this, objectToStringFunctionGetter);
                return true;
            }
        }
    }

    entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName);
    if (entry) {
        slot.setCustom(this, entry->propertyGetter());
        return true;
    }

    // Check for child frames by name before built-in properties to
    // match Mozilla. This does not match IE, but some sites end up
    // naming frames things that conflict with window properties that
    // are in Moz but not IE. Since we have some of these, we have to do
    // it the Moz way.
    if (impl()->frame()->tree()->child(identifierToAtomicString(propertyName))) {
        slot.setCustom(this, childFrameGetter);
        return true;
    }

    // Do prototype lookup early so that functions and attributes in the prototype can have
    // precedence over the index and name getters.  
    JSValue proto = prototype();
    if (proto.isObject()) {
        if (asObject(proto)->getPropertySlot(exec, propertyName, slot)) {
            if (!allowsAccess) {
                printErrorMessage(errorMessage);
                slot.setUndefined();
            }
            return true;
        }
    }

    // FIXME: Search the whole frame hierarchy somewhere around here.
    // We need to test the correct priority order.

    // allow window[1] or parent[1] etc. (#56983)
    bool ok;
    unsigned i = propertyName.toArrayIndex(ok);
    if (ok && i < impl()->frame()->tree()->childCount()) {
        slot.setCustomIndex(this, i, indexGetter);
        return true;
    }

    if (!allowsAccess) {
        printErrorMessage(errorMessage);
        slot.setUndefined();
        return true;
    }

    // Allow shortcuts like 'Image1' instead of document.images.Image1
    Document* document = impl()->frame()->document();
    if (document->isHTMLDocument()) {
        AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
        if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) {
            slot.setCustom(this, namedItemGetter);
            return true;
        }
    }

    return Base::getOwnPropertySlot(exec, propertyName, slot);
}
Example #22
0
File: clone.c Project: 1100110/dmd
FuncDeclaration *StructDeclaration::buildXopCmp(Scope *sc)
{
    //printf("StructDeclaration::buildXopCmp() %s\n", toChars());
    if (Dsymbol *cmp = search_function(this, Id::cmp))
    {
        if (FuncDeclaration *fd = cmp->isFuncDeclaration())
        {
            TypeFunction *tfcmpptr;
            {
                Scope sc;

                /* const int opCmp(ref const S s);
                 */
                Parameters *parameters = new Parameters;
                parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL));
                tfcmpptr = new TypeFunction(parameters, Type::tint32, 0, LINKd);
                tfcmpptr->mod = MODconst;
                tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &sc);
            }
            fd = fd->overloadExactMatch(tfcmpptr);
            if (fd)
                return fd;
        }
    }
    else
    {
#if 0   // FIXME: doesn't work for recursive alias this
        /* Check opCmp member exists.
         * Consider 'alias this', but except opDispatch.
         */
        Expression *e = new DsymbolExp(loc, this);
        e = new DotIdExp(loc, e, Id::cmp);
        Scope *sc2 = sc->push();
        e = e->trySemantic(sc2);
        sc2->pop();
        if (e)
        {
            Dsymbol *s = NULL;
            switch (e->op)
            {
                case TOKoverloadset:    s = ((OverExp *)e)->vars;       break;
                case TOKimport:         s = ((ScopeExp *)e)->sds;       break;
                case TOKvar:            s = ((VarExp *)e)->var;         break;
                default:                break;
            }
            if (!s || s->ident != Id::cmp)
                e = NULL;   // there's no valid member 'opCmp'
        }
        if (!e)
            return NULL;    // bitwise comparison would work
        /* Essentially, a struct which does not define opCmp is not comparable.
         * At this time, typeid(S).compare might be correct that throwing "not implement" Error.
         * But implementing it would break existing code, such as:
         *
         * struct S { int value; }  // no opCmp
         * int[S] aa;   // Currently AA key uses bitwise comparison
         *              // (It's default behavior of TypeInfo_Strust.compare).
         *
         * Not sure we should fix this inconsistency, so just keep current behavior.
         */
#else
        return NULL;
#endif
    }

    if (!xerrcmp)
    {
        Identifier *id = Lexer::idPool("_xopCmp");
        Expression *e = new IdentifierExp(loc, Id::empty);
        e = new DotIdExp(loc, e, Id::object);
        e = new DotIdExp(loc, e, id);
        e = e->semantic(sc);
        Dsymbol *s = getDsymbol(e);
        if (!s)
        {
            ::error(Loc(), "ICE: %s not found in object module. You must update druntime", id->toChars());
            fatal();
        }
        assert(s);
        xerrcmp = s->isFuncDeclaration();
    }

    Loc declLoc = Loc();    // loc is unnecessary so __xopCmp is never called directly
    Loc loc = Loc();        // loc is unnecessary so errors are gagged

    Parameters *parameters = new Parameters;
    parameters->push(new Parameter(STCref | STCconst, type, Id::p, NULL));
    parameters->push(new Parameter(STCref | STCconst, type, Id::q, NULL));
    TypeFunction *tf = new TypeFunction(parameters, Type::tint32, 0, LINKd);
    tf = (TypeFunction *)tf->semantic(loc, sc);

    Identifier *id = Lexer::idPool("__xopCmp");
    FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf);

    Expression *e1 = new IdentifierExp(loc, Id::p);
    Expression *e2 = new IdentifierExp(loc, Id::q);
    Expression *e = new CallExp(loc, new DotIdExp(loc, e1, Id::cmp), e2);

    fop->fbody = new ReturnStatement(loc, e);

    unsigned errors = global.startGagging();    // Do not report errors
    Scope *sc2 = sc->push();
    sc2->stc = 0;
    sc2->linkage = LINKd;

    fop->semantic(sc2);
    fop->semantic2(sc2);

    sc2->pop();
    if (global.endGagging(errors))    // if errors happened
        fop = xerrcmp;

    return fop;
}
Example #23
0
void TypeChecker::checkForForbiddenPrefix(Identifier Ident) {
  if (!hasEnabledForbiddenTypecheckPrefix())
    return;
  checkForForbiddenPrefix(Ident.empty() ? StringRef() : Ident.str());
}
Example #24
0
/// Print an identifier value.
static void printValue(llvm::raw_ostream &os, Identifier value) {
  os << value.str();
}
Example #25
0
PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
{
    ASSERT(!structure->isDictionary());
    ASSERT(structure->typeInfo().type() == ObjectType);

    if (Structure* existingTransition = structure->table.get(StructureTransitionTableHash::Key(RefPtr<UString::Rep>(propertyName.ustring().rep()), attributes), specificValue)) {
        ASSERT(existingTransition->m_offset != noOffset);
        offset = existingTransition->m_offset;
        return existingTransition;
    }

    return 0;
}
Example #26
0
File: attrib.c Project: smunix/ldc
void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc)
{
    struct SCstring
    {
        StorageClass stc;
        enum TOK tok;
    };

    static SCstring table[] =
    {
        { STCauto,         TOKauto },
        { STCscope,        TOKscope },
        { STCstatic,       TOKstatic },
        { STCextern,       TOKextern },
        { STCconst,        TOKconst },
        { STCfinal,        TOKfinal },
        { STCabstract,     TOKabstract },
        { STCsynchronized, TOKsynchronized },
        { STCdeprecated,   TOKdeprecated },
        { STCoverride,     TOKoverride },
        { STClazy,         TOKlazy },
        { STCalias,        TOKalias },
        { STCout,          TOKout },
        { STCin,           TOKin },
#if DMDV2
        { STCimmutable,    TOKimmutable },
        { STCshared,       TOKshared },
        { STCnothrow,      TOKnothrow },
        { STCpure,         TOKpure },
        { STCref,          TOKref },
        { STCtls,          TOKtls },
        { STCgshared,      TOKgshared },
        { STCproperty,     TOKat },
        { STCsafe,         TOKat },
        { STCtrusted,      TOKat },
        { STCdisable,       TOKat },
#endif
    };

    for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
    {
        if (stc & table[i].stc)
        {
            enum TOK tok = table[i].tok;
#if DMDV2
            if (tok == TOKat)
            {   Identifier *id;

                if (stc & STCproperty)
                    id = Id::property;
                else if (stc & STCsafe)
                    id = Id::safe;
                else if (stc & STCtrusted)
                    id = Id::trusted;
                else if (stc & STCdisable)
                    id = Id::disable;
                else
                    assert(0);
                buf->writeByte('@');
                buf->writestring(id->toChars());
            }
            else
#endif
                buf->writestring(Token::toChars(tok));
            buf->writeByte(' ');
        }
    }
}
Example #27
0
size_t Structure::remove(const Identifier& propertyName)
{
    ASSERT(!propertyName.isNull());

    checkConsistency();

    UString::Rep* rep = propertyName._ustring.rep();

    if (!m_propertyTable)
        return notFound;

#if DUMP_PROPERTYMAP_STATS
    ++numProbes;
    ++numRemoves;
#endif

    // Find the thing to remove.
    unsigned i = rep->existingHash();
    unsigned k = 0;
    unsigned entryIndex;
    UString::Rep* key = 0;
    while (1) {
        entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
        if (entryIndex == emptyEntryIndex)
            return notFound;

        key = m_propertyTable->entries()[entryIndex - 1].key;
        if (rep == key)
            break;

        if (k == 0) {
            k = 1 | doubleHash(rep->existingHash());
#if DUMP_PROPERTYMAP_STATS
            ++numCollisions;
#endif
        }

        i += k;

#if DUMP_PROPERTYMAP_STATS
        ++numRehashes;
#endif
    }

    // Replace this one element with the deleted sentinel. Also clear out
    // the entry so we can iterate all the entries as needed.
    m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = deletedSentinelIndex;

    size_t offset = m_propertyTable->entries()[entryIndex - 1].offset;

    key->deref();
    m_propertyTable->entries()[entryIndex - 1].key = 0;
    m_propertyTable->entries()[entryIndex - 1].attributes = 0;
    m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
    m_propertyTable->entries()[entryIndex - 1].offset = 0;

    if (!m_propertyTable->deletedOffsets)
        m_propertyTable->deletedOffsets = new Vector<unsigned>;
    m_propertyTable->deletedOffsets->append(offset);

    ASSERT(m_propertyTable->keyCount >= 1);
    --m_propertyTable->keyCount;
    ++m_propertyTable->deletedSentinelCount;

    if (m_propertyTable->deletedSentinelCount * 4 >= m_propertyTable->size)
        rehashPropertyMapHashTable();

    checkConsistency();
    return offset;
}
void CtrlrPanelComponentProperties::setTree (const ValueTree &_treeToEdit, const bool force)
{
	if (_treeToEdit == treeToEdit && force == false)
	{
		return;
	}

	ScopedPointer <XmlElement> xml(propertyPanel->getOpennessState());
	if (treeToEdit.hasType(Ids::panel))
	{
		panelPropertyOpennessState		= *xml;
	}
	else if (treeToEdit.hasType(Ids::modulator))
	{
		modulatorPropertyOpennessState	= *xml;
	}

	treeToEdit = _treeToEdit;

	/** Panel properties **/
	if (treeToEdit.hasType (Ids::panel))
	{
		Array <PropertyComponent*> panelProperties;
		Array <PropertyComponent*> panelEditorProperties;
		Array <PropertyComponent*> panelMidiProperties;

		for (int i=0; i<treeToEdit.getNumProperties(); i++)
		{
			if (treeToEdit.getPropertyName(i) == Ids::uiPanelImageResource)
			{
				panelProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(	treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner(),
						&resourceList,
						&resourceList
					)
				);
			}
			else if (treeToEdit.getPropertyName(i) == Ids::panelMidiInputDevice)
			{
				panelMidiProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner(),
						&midiInputDevices,
						&midiInputDevices
					)
				);
			}
			else if (treeToEdit.getPropertyName(i) == Ids::panelMidiOutputDevice)
			{
				panelMidiProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner(),
						&midiOutputDevices,
						&midiOutputDevices
					)
				);
			}
			else if (treeToEdit.getPropertyName(i) == Ids::panelMidiControllerDevice)
			{
				panelMidiProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner(),
						&midiInputDevices,
						&midiInputDevices
					)
				);
			}
			else if (treeToEdit.getPropertyName(i).toString().startsWith("panelMidi"))
			{
				panelMidiProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner()
					)
				);
			}
			else
			{
				panelProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner()
					)
				);
			}
		}

		/** Panel editor properties **/
		if (treeToEdit.getChildWithName (Ids::uiPanelEditor).isValid())
		{
			for (int i=0; i<treeToEdit.getChildWithName (Ids::uiPanelEditor).getNumProperties(); i++)
			{
				if (treeToEdit.getChildWithName (Ids::uiPanelEditor).getPropertyName(i) == Ids::uiPanelImageResource)
				{
					panelEditorProperties.add
					(
						owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
						(
							treeToEdit.getChildWithName (Ids::uiPanelEditor).getPropertyName(i),
							treeToEdit.getChildWithName(Ids::uiPanelEditor),
							&owner.getOwner(),
							&resourceList,
							&resourceList
						)
					);
				}
				else
				{
					panelEditorProperties.add
					(
						owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
						(
							treeToEdit.getChildWithName (Ids::uiPanelEditor).getPropertyName(i),
							treeToEdit.getChildWithName(Ids::uiPanelEditor),
							&owner.getOwner()
						)
					);
				}
			}
		}

		propertyPanel->clear();

		if (panelProperties.size() != 0)
			propertyPanel->addSection ("Panel", panelProperties);

		if (panelMidiProperties.size() != 0)
			propertyPanel->addSection ("MIDI", panelMidiProperties);

		if (panelMidiProperties.size() != 0)
			propertyPanel->addSection ("Editor", panelEditorProperties);
	}

	/** Modulator properties **/

	if (treeToEdit.hasType (Ids::modulator))
	{
		propertyPanel->clear();

		refreshTargetModulationPropertyList (treeToEdit);

		Array <PropertyComponent*> modulatorProperties;
		Array <PropertyComponent*> componentProperties;
		Array <PropertyComponent*> midiProperties;
		Array <PropertyComponent*> componentUIProperties;

		for (int i=0; i<treeToEdit.getNumProperties(); i++)
		{
			if (treeToEdit.getPropertyName(i) == Ids::modulatorLinkedToModulator)
			{
				modulatorProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner(),
						&modulatorList,
						&modulatorList
					)
				);
			}
			else if (treeToEdit.getPropertyName(i) == Ids::modulatorLinkedToModulatorProperty)
			{
				modulatorProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner(),
						&modulatorPropertyList,
						&modulatorPropertyList
					)
				);
			}
			else if (treeToEdit.getPropertyName(i) == Ids::modulatorLinkedToPanelProperty)
			{
				modulatorProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner(),
						&panelPropertyList,
						&panelPropertyList
					)
				);
			}
			else
			{
				modulatorProperties.add
				(
					owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
					(
						treeToEdit.getPropertyName(i),
						treeToEdit,
						&owner.getOwner(),
						&emptyValueSet,
						&emptyValueSet
					)
				);
			}
		}

		for (int i=0; i<treeToEdit.getNumChildren(); i++)
		{
			/** MIDI properties **/
			if (treeToEdit.getChild(i).hasType(Ids::midi))
			{
				for (int j=0; j<treeToEdit.getChild(i).getNumProperties(); j++)
				{
					const Identifier n = treeToEdit.getChild(i).getPropertyName(j);

					if (treeToEdit.getChild(i).getPropertyName(j) == Ids::midiMessageType)
					{
						midiProperties.add
						(
							owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
							(
								treeToEdit.getChild(i).getPropertyName(j),
								treeToEdit.getChild(i),
								&owner.getOwner(),
								&midiTemplateNames,
								&emptyValueSet)
							);
					}
					else
					{
						midiProperties.add
						(
							owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
							(
								treeToEdit.getChild(i).getPropertyName(j),
								treeToEdit.getChild(i),
								&owner.getOwner()
							)
						);
					}
				}
			}

			/** Component properties **/
			if (treeToEdit.getChild(i).hasType(Ids::component))
			{
				if (treeToEdit.getChild(i).getNumChildren() >= 0)
				{
					for (int j=0; j<treeToEdit.getChild(i).getNumChildren(); j++)
					{
						ValueTree child = treeToEdit.getChild(i).getChild(j);

						for (int k=0; k<child.getNumProperties(); k++)
						{
							if (child.getPropertyName(k) == Ids::uiTabsTabBackgroundImage)
							{
								componentProperties.add
								(
									owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
									(
										child.getPropertyName(k),
										child,
										&owner.getOwner(),
										&resourceList,
										&resourceList
									)
								);
							}
							else if (child.getPropertyName(k) == Ids::uiEnvelopePointLinkX || child.getPropertyName(k) == Ids::uiEnvelopePointLinkY)
							{
								componentProperties.add
								(
									owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
									(
										child.getPropertyName(k),
										child,
										&owner.getOwner(),
										&modulatorList,
										&modulatorList
									)
								);
							}
							else
							{
								componentProperties.add
								(
									owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
									(
										child.getPropertyName(k),
										child,
										&owner.getOwner()
									)
								);
							}
						}
					}
				}

				for (int j=0; j<treeToEdit.getChild(i).getNumProperties(); j++)
				{
					const Identifier n = treeToEdit.getChild(i).getPropertyName(j);

					if (n == Ids::uiImageResource
						|| n == Ids::uiImageSliderResource
						|| n == Ids::uiImageButtonResource
						|| n == Ids::uiGroupBackgroundImage
						|| n == Ids::uiTabsTabBackgroundImage
						|| n == Ids::uiXYSurfaceBgImageResource)
					{
						componentProperties.add
						(
							owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
							(
								treeToEdit.getChild(i).getPropertyName(j),
								treeToEdit.getChild(i),
								&owner.getOwner(),
								&resourceList,
								&resourceList
							)
						);
					}
					else if (n.toString().startsWith("ui"))
					{
						componentUIProperties.add
						(
							owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
							(
								treeToEdit.getChild(i).getPropertyName(j),
								treeToEdit.getChild(i),
								&owner.getOwner()
							)
						);
					}
					else
					{
						componentProperties.add
						(
							owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty
							(
								treeToEdit.getChild(i).getPropertyName(j),
								treeToEdit.getChild(i),
								&owner.getOwner()
							)
						);
					}
				}
			}
		}

		if (modulatorProperties.size() != 0)
			propertyPanel->addSection ("Modulator", modulatorProperties);

		if (midiProperties.size() != 0)
			propertyPanel->addSection ("MIDI", midiProperties);

		if (componentProperties.size() != 0)
			propertyPanel->addSection ("Component generic", componentProperties);

		if (componentUIProperties.size() != 0)
			propertyPanel->addSection ("Component", componentUIProperties);
	}
}
Example #29
0
static NPIdentifier npIdentifierFromIdentifier(const Identifier& identifier)
{
    return static_cast<NPIdentifier>(IdentifierRep::get(identifier.ustring().utf8().data()));
}
Example #30
0
// ECMA 8.6.2.2
void JSObject::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
{
  assert(value);

  // non-standard netscape extension
  if (propertyName == exec->propertyNames().underscoreProto) {
    JSObject* proto = value->getObject();
    while (proto) {
      if (proto == this) {
        throwError(exec, GeneralError, "cyclic __proto__ value");
        return;
      }
      proto = proto->prototype() ? proto->prototype()->getObject() : 0;
    }

    setPrototype(value);
    return;
  }

  // putValue() is used for JS assignemnts. It passes no attribute.
  // Assume that a C++ implementation knows what it is doing
  // and don't spend time doing a read-only check for it.
  bool checkRO = (attr == None || attr == DontDelete);

  if (checkRO) {
    // Check for static properties that are ReadOnly; the property map will check the dynamic properties.
    // We don't have to worry about setters being read-only as they can't be added with such an attribute.
    // We also need to inherit any attributes we have from the entry
    const HashEntry* entry = findPropertyHashEntry(propertyName);
    if (entry) {
      if (entry->attr & ReadOnly) {
#ifdef KJS_VERBOSE
        fprintf( stderr, "WARNING: static property %s is ReadOnly\n", propertyName.ascii() );
#endif
        return;
      }
      attr = entry->attr;
    }
  }

  // Check if there are any setters or getters in the prototype chain
  JSObject *obj = this;
  bool hasGettersOrSetters = false;
  while (true) {
    if (obj->_prop.hasGetterSetterProperties()) {
      hasGettersOrSetters = true;
      break;
    }

    if (!obj->_proto->isObject())
      break;

    obj = static_cast<JSObject *>(obj->_proto);
  }

  if (hasGettersOrSetters) {
    obj = this;
    while (true) {
      unsigned attributes;
      if (JSValue *gs = obj->_prop.get(propertyName, attributes)) {
        if (attributes & GetterSetter) {
          JSObject *setterFunc = static_cast<GetterSetterImp *>(gs)->getSetter();

          if (!setterFunc) {
            throwSetterError(exec);
            return;
          }

          List args;
          args.append(value);

          setterFunc->call(exec, this, args);
          return;
        } else {
          // If there's an existing property on the object or one of its
          // prototype it should be replaced, so we just break here.
          break;
        }
      }

      if (!obj->_proto->isObject())
        break;

      obj = static_cast<JSObject *>(obj->_proto);
    }
  }

  _prop.put(propertyName,value,attr,checkRO);
}