Example #1
0
Value ObjectProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
{
    switch(id)
    {
        case ToString:
        // fall through
        case ToLocaleString:
            return String("[object " + thisObj.className() + "]");
        case ValueOf:
            return thisObj;
        case HasOwnProperty:
        {
            // Same as hasProperty() but without checking the prototype
            Identifier propertyName(args[0].toString(exec));
            Value tempProto(thisObj.imp()->prototype());
            thisObj.imp()->setPrototype(Value());
            bool exists = thisObj.hasProperty(exec, propertyName);
            thisObj.imp()->setPrototype(tempProto);
            return Value(exists ? BooleanImp::staticTrue : BooleanImp::staticFalse);
        }
        case IsPrototypeOf:
        {
            Value v = args[0];
            for(; v.isValid() && v.isA(ObjectType); v = Object::dynamicCast(v).prototype())
            {
                if(v.imp() == thisObj.imp())
                    return Value(BooleanImp::staticTrue);
            }
            return Value(BooleanImp::staticFalse);
        }
        case PropertyIsEnumerable:
        {
            Identifier propertyName(args[0].toString(exec));
            ObjectImp *obj = static_cast< ObjectImp * >(thisObj.imp());

            int attributes;
            ValueImp *v = obj->_prop.get(propertyName, attributes);
            if(v)
                return Value((attributes & DontEnum) ? BooleanImp::staticFalse : BooleanImp::staticTrue);

            if(propertyName == specialPrototypePropertyName)
                return Value(BooleanImp::staticFalse);

            const HashEntry *entry = obj->findPropertyHashEntry(propertyName);
            return Value((entry && !(entry->attr & DontEnum)) ? BooleanImp::staticTrue : BooleanImp::staticFalse);
        }
    }

    return Undefined();
}
Example #2
0
Value DOMCSSStyleSheetProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
  KJS_CHECK_THIS( KJS::DOMCSSStyleSheet, thisObj );
  DOM::CSSStyleSheet styleSheet = static_cast<DOMCSSStyleSheet *>(thisObj.imp())->toCSSStyleSheet();

  switch (id) {
    case DOMCSSStyleSheet::InsertRule:
      return Number(styleSheet.insertRule(args[0].toString(exec).string(),(long unsigned int)args[1].toInteger(exec)));
    case DOMCSSStyleSheet::DeleteRule:
      styleSheet.deleteRule(args[0].toInteger(exec));
      return Undefined();
    // IE extensions
    case DOMCSSStyleSheet::AddRule: {
      //Unpassed/-1 means append. Since insertRule is picky (throws exceptions)
      //we adjust it to the desired length
      unsigned long index  = args[2].toInteger(exec);
      unsigned long length = styleSheet.cssRules().length();
      if (args[2].type() == UndefinedType) index = length;
      if (index > length)                  index = length;
      DOM::DOMString str = args[0].toString(exec).string() + " { " + args[1].toString(exec).string() + " } ";
      return Number(styleSheet.insertRule(str,index));
    }
    case DOMCSSStyleSheet::RemoveRule: {
      int index = args.size() > 0 ? args[0].toInteger(exec) : 0 /*first one*/;
      styleSheet.deleteRule(index);
      return Undefined();
    }
    default:
      return Undefined();
  }
}
Example #3
0
Value NavigatorFunc::tryCall(ExecState *exec, Object &thisObj, const List &)
{
    KJS_CHECK_THIS(KJS::Navigator, thisObj);
    Navigator *nav = static_cast< Navigator * >(thisObj.imp());
    // javaEnabled()
    return Boolean(nav->part()->javaEnabled());
}
Example #4
0
Value MozillaSidebarExtensionFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
    KJS_CHECK_THIS(KJS::MozillaSidebarExtension, thisObj);
    MozillaSidebarExtension *mse = static_cast< MozillaSidebarExtension * >(thisObj.imp());

    KHTMLPart *part = mse->part();
    if(!part)
        return Undefined();

    // addPanel()  id == 0
    KParts::BrowserExtension *ext = part->browserExtension();
    if(ext)
    {
        QString url, name;
        if(args.size() == 1)
        {   // I've seen this, don't know if it's legal.
            name = QString::null;
            url = args[0].toString(exec).qstring();
        }
        else if(args.size() == 2 || args.size() == 3)
        {
            name = args[0].toString(exec).qstring();
            url = args[1].toString(exec).qstring();
            // 2 is the "CURL" which I don't understand and don't think we need.
        }
        else
        {
            return Boolean(false);
        }
        emit ext->addWebSideBar(KURL(url), name);
        return Boolean(true);
    }

    return Undefined();
}
Example #5
0
Value DOMParserProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
  if (!thisObj.inherits(&DOMParser::info)) {
    Object err = Error::create(exec,TypeError);
    exec->setException(err);
    return err;
  }

  DOMParser *parser = static_cast<DOMParser *>(thisObj.imp());

  switch (id) {
  case DOMParser::ParseFromString:
    {
      if (args.size() != 2) {
				return Undefined();
      }

      TQString str = args[0].toString(exec).qstring();
      TQString contentType = args[1].toString(exec).qstring().stripWhiteSpace();

      if (contentType == "text/xml" || contentType == "application/xml" || contentType == "application/xhtml+xml") {
        DocumentImpl *docImpl = parser->doc->implementation()->createDocument();

        docImpl->open();
        docImpl->write(str);
        docImpl->finishParsing();
        docImpl->close();

        return getDOMNode(exec, docImpl);
      }
    }
  }

  return Undefined();
}
Example #6
0
Value DOMCSSPrimitiveValueProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
    KJS_CHECK_THIS(KJS::DOMCSSPrimitiveValue, thisObj);
    DOM::CSSPrimitiveValue val = static_cast< DOMCSSPrimitiveValue * >(thisObj.imp())->toCSSPrimitiveValue();
    switch(id)
    {
        case DOMCSSPrimitiveValue::SetFloatValue:
            val.setFloatValue(args[0].toInteger(exec), args[1].toNumber(exec));
            return Undefined();
        case DOMCSSPrimitiveValue::GetFloatValue:
            return Number(val.getFloatValue(args[0].toInteger(exec)));
        case DOMCSSPrimitiveValue::SetStringValue:
            val.setStringValue(args[0].toInteger(exec), args[1].toString(exec).string());
            return Undefined();
        case DOMCSSPrimitiveValue::GetStringValue:
            return String(val.getStringValue());
        case DOMCSSPrimitiveValue::GetCounterValue:
            return getDOMCounter(exec, val.getCounterValue());
        case DOMCSSPrimitiveValue::GetRectValue:
            return getDOMRect(exec, val.getRectValue());
        case DOMCSSPrimitiveValue::GetRGBColorValue:
            return getDOMRGBColor(exec, val.getRGBColorValue());
        default:
            return Undefined();
    }
}
Example #7
0
Value MimeTypesFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
    KJS_CHECK_THIS(KJS::MimeTypes, thisObj);
    KJS::MimeTypes *base = static_cast< KJS::MimeTypes * >(thisObj.imp());
    if(!base->pluginsEnabled())
    {
        if(id == MimeTypes_Item || id == MimeTypes_NamedItem)
            return Undefined();
    }
    else
    {
        switch(id)
        {
            case MimeTypes_Item:
            {
                bool ok;
                unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
                if(ok && i < base->mimes->count())
                    return Value(new MimeType(exec, base->mimes->at(i)));
                return Undefined();
            }
            case MimeTypes_NamedItem:
                UString s = args[0].toString(exec);
                return base->mimeTypeByName(exec, s.qstring());
        }
    }
    kdDebug(6070) << "WARNING: Unhandled token in MimeTypesFunc::tryCall : " << id << endl;
    return Undefined();
}
Example #8
0
Value DOMCSSStyleDeclarationProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
    KJS_CHECK_THIS(KJS::DOMCSSStyleDeclaration, thisObj);
    DOM::CSSStyleDeclaration styleDecl = static_cast< DOMCSSStyleDeclaration * >(thisObj.imp())->toStyleDecl();
    String str = args[0].toString(exec);
    DOM::DOMString s = str.value().string();

    switch(id)
    {
        case DOMCSSStyleDeclaration::GetPropertyValue:
            return String(styleDecl.getPropertyValue(s));
        case DOMCSSStyleDeclaration::GetPropertyCSSValue:
            return getDOMCSSValue(exec, styleDecl.getPropertyCSSValue(s));
        case DOMCSSStyleDeclaration::RemoveProperty:
            return String(styleDecl.removeProperty(s));
        case DOMCSSStyleDeclaration::GetPropertyPriority:
            return String(styleDecl.getPropertyPriority(s));
        case DOMCSSStyleDeclaration::SetProperty:
            styleDecl.setProperty(args[0].toString(exec).string(), args[1].toString(exec).string(), args[2].toString(exec).string());
            return Undefined();
        case DOMCSSStyleDeclaration::Item:
            return String(styleDecl.item(args[0].toInteger(exec)));
        default:
            return Undefined();
    }
}
Example #9
0
Value DOMStyleSheetListFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
    KJS_CHECK_THIS(KJS::DOMStyleSheetList, thisObj);
    DOM::StyleSheetList styleSheetList = static_cast< DOMStyleSheetList * >(thisObj.imp())->toStyleSheetList();
    if(id == DOMStyleSheetList::Item)
        return getDOMStyleSheet(exec, styleSheetList.item(args[0].toInteger(exec)));
    return Undefined();
}
Example #10
0
void ArrayInstanceImp::sort(ExecState *exec, Object &compareFunction)
{
    int lengthNotIncludingUndefined = pushUndefinedObjectsToEnd(exec);

    CompareWithCompareFunctionArguments args(exec, compareFunction.imp());
    compareWithCompareFunctionArguments = &args;
    qsort(storage, lengthNotIncludingUndefined, sizeof(ValueImp *), compareWithCompareFunctionForQSort);
    compareWithCompareFunctionArguments = 0;
}
Example #11
0
DOM::CSSRule toCSSRule(const Value &val)
{
    Object obj = Object::dynamicCast(val);
    if(!obj.isValid() || !obj.inherits(&DOMCSSRule::info))
        return DOM::CSSRule();

    const DOMCSSRule *dobj = static_cast< const DOMCSSRule * >(obj.imp());
    return dobj->toCSSRule();
}
DOM::Node KJS::toNode(const Value& val)
{
  Object obj = Object::dynamicCast(val);
  if (obj.isNull() || !obj.inherits(&DOMNode::info))
    return DOM::Node();

  const DOMNode *dobj = static_cast<const DOMNode*>(obj.imp());
  return dobj->toNode();
}
NativeErrorImp::NativeErrorImp(ExecState *exec, FunctionPrototypeImp *funcProto,
                               const Object &prot)
  : InternalFunctionImp(funcProto), proto(0)
{
  Value protect(this);
  proto = static_cast<ObjectImp*>(prot.imp());

  putDirect(lengthPropertyName, NumberImp::one(), DontDelete|ReadOnly|DontEnum); // ECMA 15.11.7.5
  putDirect(prototypePropertyName, proto, 0);
}
Example #14
0
Value DOMCSSRuleListFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
  KJS_CHECK_THIS( KJS::DOMCSSRuleList, thisObj );
  DOM::CSSRuleList cssRuleList = static_cast<DOMCSSRuleList *>(thisObj.imp())->toCSSRuleList();
  switch (id) {
    case DOMCSSRuleList::Item:
      return getDOMCSSRule(exec,cssRuleList.item(args[0].toInteger(exec)));
    default:
      return Undefined();
  }
}
Example #15
0
Value DOMCSSRuleFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
  KJS_CHECK_THIS( KJS::DOMCSSRule, thisObj );
  DOM::CSSRule cssRule = static_cast<DOMCSSRule *>(thisObj.imp())->toCSSRule();

  if (cssRule.type() == DOM::CSSRule::MEDIA_RULE) {
    DOM::CSSMediaRule rule = static_cast<DOM::CSSMediaRule>(cssRule);
    if (id == DOMCSSRule::Media_InsertRule)
      return Number(rule.insertRule(args[0].toString(exec).string(),args[1].toInteger(exec)));
    else if (id == DOMCSSRule::Media_DeleteRule)
      rule.deleteRule(args[0].toInteger(exec));
  }

  return Undefined();
}
Example #16
0
Value KJS::DOMMediaListProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
  KJS_CHECK_THIS( KJS::DOMMediaList, thisObj );
  DOM::MediaList mediaList = static_cast<DOMMediaList *>(thisObj.imp())->toMediaList();
  switch (id) {
    case DOMMediaList::Item:
      return String(mediaList.item(args[0].toInteger(exec)));
    case DOMMediaList::DeleteMedium:
      mediaList.deleteMedium(args[0].toString(exec).string());
      return Undefined();
    case DOMMediaList::AppendMedium:
      mediaList.appendMedium(args[0].toString(exec).string());
      return Undefined();
    default:
      return Undefined();
  }
}
Example #17
0
Boolean DOMObject::hasInstance(ExecState *exec, const Value &value)
{
    if(value.type() != ObjectType)
        return Boolean(false);

    Value prot = get(exec, prototypePropertyName);
    if(prot.type() != ObjectType && prot.type() != NullType)
    {
        Object err = Error::create(exec, TypeError,
                                   "Invalid prototype encountered "
                                   "in instanceof operation.");
        exec->setException(err);
        return Boolean(false);
    }

    Object v = Object(static_cast< ObjectImp * >(value.imp()));
    while((v = Object::dynamicCast(v.prototype())).imp())
    {
        if(v.imp() == prot.imp())
            return Boolean(true);
    }
    return Boolean(false);
}
Example #18
0
Value PluginFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
    KJS_CHECK_THIS(KJS::Plugin, thisObj);
    KJS::Plugin *plugin = static_cast< KJS::Plugin * >(thisObj.imp());
    switch(id)
    {
        case Plugin_Item:
        {
            bool ok;
            unsigned int i = args[0].toString(exec).toArrayIndex(&ok);
            if(ok && i < plugin->pluginInfo()->mimes.count())
                return Value(new MimeType(exec, plugin->pluginInfo()->mimes.at(i)));
            return Undefined();
        }
        case Plugin_NamedItem:
        {
            UString s = args[0].toString(exec);
            return plugin->mimeByName(exec, s.qstring());
        }
        default:
            kdDebug(6070) << "WARNING: Unhandled token in PluginFunc::tryCall : " << id << endl;
            return Undefined();
    }
}
Example #19
0
// ECMA 15.4.4
Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
{
    unsigned int length = thisObj.get(exec, lengthPropertyName).toUInt32(exec);

    Value result;
    switch(id)
    {
        case ToLocaleString:
        case ToString:

            if(!thisObj.inherits(&ArrayInstanceImp::info))
            {
                Object err = Error::create(exec, TypeError);
                exec->setException(err);
                return err;
            }

        // fall through
        case Join:
        {
            UString separator = ",";
            UString str = "";

            if(id == Join && args.size() > 0 && !args[0].isA(UndefinedType))
                separator = args[0].toString(exec);
            for(unsigned int k = 0; k < length; k++)
            {
                if(k >= 1)
                    str += separator;

                Value element = thisObj.get(exec, k);
                if(element.type() == UndefinedType || element.type() == NullType)
                    continue;

                bool fallback = false;
                if(id == ToLocaleString)
                {
                    Object o = element.toObject(exec);
                    Object conversionFunction = Object::dynamicCast(o.get(exec, toLocaleStringPropertyName));
                    if(conversionFunction.isValid() && conversionFunction.implementsCall())
                    {
                        str += conversionFunction.call(exec, o, List()).toString(exec);
                    }
                    else
                    {
                        // try toString() fallback
                        fallback = true;
                    }
                }
                if(id == ToString || id == Join || fallback)
                {
                    if(element.type() == ObjectType)
                    {
                        Object o = Object::dynamicCast(element);
                        Object conversionFunction = Object::dynamicCast(o.get(exec, toStringPropertyName));
                        if(conversionFunction.isValid() && conversionFunction.implementsCall())
                        {
                            str += conversionFunction.call(exec, o, List()).toString(exec);
                        }
                        else
                        {
                            UString msg = "Can't convert " + o.className() + " object to string";
                            Object error = Error::create(exec, RangeError, msg.cstring().c_str());
                            exec->setException(error);
                            return error;
                        }
                    }
                    else
                    {
                        str += element.toString(exec);
                    }
                }
                if(exec->hadException())
                    break;
            }
            result = String(str);
            break;
        }
        case Concat:
        {
            Object arr = Object::dynamicCast(exec->lexicalInterpreter()->builtinArray().construct(exec, List::empty()));
            int n = 0;
            Value curArg = thisObj;
            Object curObj = Object::dynamicCast(thisObj);
            ListIterator it = args.begin();
            for(;;)
            {
                if(curArg.type() == ObjectType && curObj.inherits(&ArrayInstanceImp::info))
                {
                    unsigned int k = 0;
                    // Older versions tried to optimize out getting the length of thisObj
                    // by checking for n != 0, but that doesn't work if thisObj is an empty array.
                    length = curObj.get(exec, lengthPropertyName).toUInt32(exec);
                    while(k < length)
                    {
                        if(curObj.hasProperty(exec, k))
                            arr.put(exec, n, curObj.get(exec, k));
                        n++;
                        k++;
                    }
                }
                else
                {
                    arr.put(exec, n, curArg);
                    n++;
                }
                if(it == args.end())
                    break;
                curArg = *it;
                curObj = Object::dynamicCast(it++); // may be 0
            }
            arr.put(exec, lengthPropertyName, Number(n), DontEnum | DontDelete);

            result = arr;
            break;
        }
        case Pop:
        {
            if(length == 0)
            {
                thisObj.put(exec, lengthPropertyName, Number(length), DontEnum | DontDelete);
                result = Undefined();
            }
            else
            {
                result = thisObj.get(exec, length - 1);
                thisObj.put(exec, lengthPropertyName, Number(length - 1), DontEnum | DontDelete);
            }
            break;
        }
        case Push:
        {
            for(int n = 0; n < args.size(); n++)
                thisObj.put(exec, length + n, args[n]);
            length += args.size();
            thisObj.put(exec, lengthPropertyName, Number(length), DontEnum | DontDelete);
            result = Number(length);
            break;
        }
        case Reverse:
        {

            unsigned int middle = length / 2;

            for(unsigned int k = 0; k < middle; k++)
            {
                unsigned lk1 = length - k - 1;
                Value obj = thisObj.get(exec, k);
                Value obj2 = thisObj.get(exec, lk1);
                if(thisObj.hasProperty(exec, lk1))
                {
                    if(thisObj.hasProperty(exec, k))
                    {
                        thisObj.put(exec, k, obj2);
                        thisObj.put(exec, lk1, obj);
                    }
                    else
                    {
                        thisObj.put(exec, k, obj2);
                        thisObj.deleteProperty(exec, lk1);
                    }
                }
                else
                {
                    if(thisObj.hasProperty(exec, k))
                    {
                        thisObj.deleteProperty(exec, k);
                        thisObj.put(exec, lk1, obj);
                    }
                    else
                    {
                        // why delete something that's not there ? Strange.
                        thisObj.deleteProperty(exec, k);
                        thisObj.deleteProperty(exec, lk1);
                    }
                }
            }
            result = thisObj;
            break;
        }
        case Shift:
        {
            if(length == 0)
            {
                thisObj.put(exec, lengthPropertyName, Number(length), DontEnum | DontDelete);
                result = Undefined();
            }
            else
            {
                result = thisObj.get(exec, 0);
                for(unsigned int k = 1; k < length; k++)
                {
                    if(thisObj.hasProperty(exec, k))
                    {
                        Value obj = thisObj.get(exec, k);
                        thisObj.put(exec, k - 1, obj);
                    }
                    else
                        thisObj.deleteProperty(exec, k - 1);
                }
                thisObj.deleteProperty(exec, length - 1);
                thisObj.put(exec, lengthPropertyName, Number(length - 1), DontEnum | DontDelete);
            }
            break;
        }
        case Slice:
        {
            // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10

            // We return a new array
            Object resObj = Object::dynamicCast(exec->lexicalInterpreter()->builtinArray().construct(exec, List::empty()));
            result = resObj;
            int begin = 0;
            if(args[0].type() != UndefinedType)
            {
                begin = args[0].toInteger(exec);
                if(begin < 0)
                    begin = maxInt(begin + length, 0);
                else
                    begin = minInt(begin, length);
            }
            int end = length;
            if(args[1].type() != UndefinedType)
            {
                end = args[1].toInteger(exec);
                if(end < 0)
                    end = maxInt(end + length, 0);
                else
                    end = minInt(end, length);
            }

            // printf( "Slicing from %d to %d \n", begin, end );
            int n = 0;
            for(int k = begin; k < end; k++, n++)
            {
                if(thisObj.hasProperty(exec, k))
                {
                    Value obj = thisObj.get(exec, k);
                    resObj.put(exec, n, obj);
                }
            }
            resObj.put(exec, lengthPropertyName, Number(n), DontEnum | DontDelete);
            break;
        }
        case Sort:
        {
#if 0
    printf("KJS Array::Sort length=%d\n", length);
    for ( unsigned int i = 0 ; i<length ; ++i )
      printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(exec, i).toString(exec).ascii() );
#endif
            Object sortFunction;
            bool useSortFunction = (args[0].type() != UndefinedType);
            if(useSortFunction)
            {
                sortFunction = args[0].toObject(exec);
                if(!sortFunction.implementsCall())
                    useSortFunction = false;
            }

            if(thisObj.imp()->classInfo() == &ArrayInstanceImp::info)
            {
                if(useSortFunction)
                    ((ArrayInstanceImp *)thisObj.imp())->sort(exec, sortFunction);
                else
                    ((ArrayInstanceImp *)thisObj.imp())->sort(exec);
                result = thisObj;
                break;
            }

            if(length == 0)
            {
                thisObj.put(exec, lengthPropertyName, Number(0), DontEnum | DontDelete);
                result = thisObj;
                break;
            }

            // "Min" sort. Not the fastest, but definitely less code than heapsort
            // or quicksort, and much less swapping than bubblesort/insertionsort.
            for(unsigned int i = 0; i < length - 1; ++i)
            {
                Value iObj = thisObj.get(exec, i);
                unsigned int themin = i;
                Value minObj = iObj;
                for(unsigned int j = i + 1; j < length; ++j)
                {
                    Value jObj = thisObj.get(exec, j);
                    double cmp;
                    if(jObj.type() == UndefinedType)
                    {
                        cmp = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
                    }
                    else if(minObj.type() == UndefinedType)
                    {
                        cmp = -1;
                    }
                    else if(useSortFunction)
                    {
                        List l;
                        l.append(jObj);
                        l.append(minObj);
                        cmp = sortFunction.call(exec, exec->dynamicInterpreter()->globalObject(), l).toNumber(exec);
                    }
                    else
                    {
                        cmp = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
                    }
                    if(cmp < 0)
                    {
                        themin = j;
                        minObj = jObj;
                    }
                }
                // Swap themin and i
                if(themin > i)
                {
                    // printf("KJS Array::Sort: swapping %d and %d\n", i, themin );
                    thisObj.put(exec, i, minObj);
                    thisObj.put(exec, themin, iObj);
                }
            }
#if 0
    printf("KJS Array::Sort -- Resulting array:\n");
    for ( unsigned int i = 0 ; i<length ; ++i )
      printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(exec, i).toString(exec).ascii() );
#endif
            result = thisObj;
            break;
        }
        case Splice:
        {
            // 15.4.4.12 - oh boy this is huge
            Object resObj = Object::dynamicCast(exec->lexicalInterpreter()->builtinArray().construct(exec, List::empty()));
            result = resObj;
            int begin = args[0].toUInt32(exec);
            if(begin < 0)
                begin = maxInt(begin + length, 0);
            else
                begin = minInt(begin, length);
            unsigned int deleteCount = minInt(maxInt(args[1].toUInt32(exec), 0), length - begin);

            // printf( "Splicing from %d, deleteCount=%d \n", begin, deleteCount );
            for(unsigned int k = 0; k < deleteCount; k++)
            {
                if(thisObj.hasProperty(exec, k + begin))
                {
                    Value obj = thisObj.get(exec, k + begin);
                    resObj.put(exec, k, obj);
                }
            }
            resObj.put(exec, lengthPropertyName, Number(deleteCount), DontEnum | DontDelete);

            unsigned int additionalArgs = maxInt(args.size() - 2, 0);
            if(additionalArgs != deleteCount)
            {
                if(additionalArgs < deleteCount)
                {
                    for(unsigned int k = begin; k < length - deleteCount; ++k)
                    {
                        if(thisObj.hasProperty(exec, k + deleteCount))
                        {
                            Value obj = thisObj.get(exec, k + deleteCount);
                            thisObj.put(exec, k + additionalArgs, obj);
                        }
                        else
                            thisObj.deleteProperty(exec, k + additionalArgs);
                    }
                    for(unsigned int k = length; k > length - deleteCount + additionalArgs; --k)
                        thisObj.deleteProperty(exec, k - 1);
                }
                else
                {
                    for(unsigned int k = length - deleteCount; (int)k > begin; --k)
                    {
                        if(thisObj.hasProperty(exec, k + deleteCount - 1))
                        {
                            Value obj = thisObj.get(exec, k + deleteCount - 1);
                            thisObj.put(exec, k + additionalArgs - 1, obj);
                        }
                        else
                            thisObj.deleteProperty(exec, k + additionalArgs - 1);
                    }
                }
            }
            for(unsigned int k = 0; k < additionalArgs; ++k)
            {
                thisObj.put(exec, k + begin, args[k + 2]);
            }
            thisObj.put(exec, lengthPropertyName, Number(length - deleteCount + additionalArgs), DontEnum | DontDelete);
            break;
        }
        case UnShift:
        { // 15.4.4.13
            unsigned int nrArgs = args.size();
            for(unsigned int k = length; k > 0; --k)
            {
                if(thisObj.hasProperty(exec, k - 1))
                {
                    Value obj = thisObj.get(exec, k - 1);
                    thisObj.put(exec, k + nrArgs - 1, obj);
                }
                else
                {
                    thisObj.deleteProperty(exec, k + nrArgs - 1);
                }
            }
            for(unsigned int k = 0; k < nrArgs; ++k)
                thisObj.put(exec, k, args[k]);
            result = Number(length + nrArgs);
            thisObj.put(exec, lengthPropertyName, result, DontEnum | DontDelete);
            break;
        }
        default:
            assert(0);
            break;
    }
    return result;
}
Example #20
0
Value RegExpProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
{
  if (!thisObj.inherits(&RegExpImp::info)) {
    Object err = Error::create(exec,TypeError);
    exec->setException(err);
    return err;
  }

  RegExpImp *reimp = static_cast<RegExpImp*>(thisObj.imp());
  RegExp *re = reimp->regExp();
  String s;
  UString str;
  switch (id) {
  case Exec:      // 15.10.6.2
  case Test:
  {
    s = args[0].toString(exec);
    int length = s.value().size();
    Value lastIndex = thisObj.get(exec,"lastIndex");
    int i = lastIndex.isNull() ? 0 : lastIndex.toInt32(exec);
    bool globalFlag = thisObj.get(exec,"global").toBoolean(exec);
    if (!globalFlag)
      i = 0;
    if (i < 0 || i > length) {
      thisObj.put(exec,"lastIndex", Number(0), DontDelete | DontEnum);
      if (id == Test)
        return Boolean(false);
      else
        Null();
    }
    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->interpreter()->builtinRegExp().imp());
    int **ovector = regExpObj->registerRegexp( re, s.value() );

    str = re->match(s.value(), i, 0L, ovector);
    regExpObj->setSubPatterns(re->subPatterns());

    if (id == Test)
      return Boolean(!str.isNull());

    if (str.isNull()) // no match
    {
      if (globalFlag)
        thisObj.put(exec,"lastIndex",Number(0), DontDelete | DontEnum);
      return Null();
    }
    else // success
    {
      if (globalFlag)
        thisObj.put(exec,"lastIndex",Number( (*ovector)[1] ), DontDelete | DontEnum);
      return regExpObj->arrayOfMatches(exec,str);
    }
  }
  break;
  case ToString:
    s = thisObj.get(exec,"source").toString(exec);
    str = "/";
    str += s.value();
    str += "/";
    // TODO append the flags
    return String(str);
  }

  return Undefined();
}
Example #21
0
bool KJSDebugWin::exception(ExecState *exec, const Value &value, bool inTryCatch)
{
    assert(value.isValid());

    // Ignore exceptions that will be caught by the script
    if(inTryCatch)
        return true;

    KParts::ReadOnlyPart *part = static_cast< ScriptInterpreter * >(exec->interpreter())->part();
    KHTMLPart *khtmlpart = ::qt_cast< KHTMLPart * >(part);
    if(khtmlpart && !khtmlpart->settings()->isJavaScriptErrorReportingEnabled())
        return true;

    QWidget *dlgParent = (m_evalDepth == 0) ? (QWidget *)part->widget() : (QWidget *)this;

    QString exceptionMsg = value.toString(exec).qstring();

    // Syntax errors are a special case. For these we want to display the url & lineno,
    // which isn't included in the exception messeage. So we work it out from the values
    // passed to sourceParsed()
    Object valueObj = Object::dynamicCast(value);
    Object syntaxError = exec->interpreter()->builtinSyntaxError();
    if(valueObj.isValid() && valueObj.get(exec, "constructor").imp() == syntaxError.imp())
    {
        Value sidValue = valueObj.get(exec, "sid");
        if(sidValue.isA(NumberType))
        { // sid is not set for Function() constructor
            int sourceId = (int)sidValue.toNumber(exec);
            assert(m_sourceFragments[sourceId]);
            exceptionMsg = i18n("Parse error at %1 line %2")
                               .arg(m_sourceFragments[sourceId]->sourceFile->url)
                               .arg(m_sourceFragments[sourceId]->baseLine + m_sourceFragments[sourceId]->errorLine - 1);
        }
    }

    bool dontShowAgain = false;
    if(m_execsCount == 0)
    {
        // An exception occurred and we're not currently executing any code... this can
        // happen in some cases e.g. a parse error, or native code accessing funcitons like
        // Object::put()
        QString msg = i18n("An error occurred while attempting to run a script on this page.\n\n%1").arg(exceptionMsg);
        KJSErrorDialog dlg(dlgParent, msg, false);
        dlg.exec();
        dontShowAgain = dlg.dontShowAgain();
    }
    else
    {
        Context ctx = m_execs[m_execsCount - 1]->context();
        SourceFragment *sourceFragment = m_sourceFragments[ctx.sourceId()];
        QString msg = i18n("An error occurred while attempting to run a script on this page.\n\n%1 line %2:\n%3")
                          .arg(KStringHandler::rsqueeze(sourceFragment->sourceFile->url, 80),
                               QString::number(sourceFragment->baseLine + ctx.curStmtFirstLine() - 1), exceptionMsg);

        KJSErrorDialog dlg(dlgParent, msg, true);
        dlg.exec();
        dontShowAgain = dlg.dontShowAgain();

        if(dlg.debugSelected())
        {
            m_mode = Next;
            m_steppingDepth = m_execsCount - 1;
            enterSession(exec);
        }
    }

    if(dontShowAgain)
    {
        KConfig *config = kapp->config();
        KConfigGroupSaver saver(config, QString::fromLatin1("Java/JavaScript Settings"));
        config->writeEntry("ReportJavaScriptErrors", QVariant(false, 0));
        config->sync();
        QByteArray data;
        kapp->dcopClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", data);
    }

    return (m_mode != Stop);
}
Example #22
0
// ECMA 15.9.3
Object DateObjectImp::construct(ExecState *exec, const List &args)
{
  int numArgs = args.size();

#ifdef KJS_VERBOSE
  fprintf(stderr,"DateObjectImp::construct - %d args\n", numArgs);
#endif
  double value;

  if (numArgs == 0) { // new Date() ECMA 15.9.3.3
#ifdef HAVE_SYS_TIMEB_H
#  if defined(__BORLANDC__)
    struct timeb timebuffer;
    ftime(&timebuffer);
#  else
    struct _timeb timebuffer;
    _ftime(&timebuffer);
#  endif
    double utc = floor((double)timebuffer.time * 1000.0 + (double)timebuffer.millitm);
#else
    struct timeval tv;
    gettimeofday(&tv, 0L);
    double utc = floor((double)tv.tv_sec * 1000.0 + (double)tv.tv_usec / 1000.0);
#endif
    value = utc;
  } else if (numArgs == 1) {
    Value prim = args[0].toPrimitive(exec);
    if (prim.isA(StringType))
      value = parseDate(prim.toString(exec));
    else
      value = prim.toNumber(exec);
  } else {
    if (isNaN(args[0].toNumber(exec))
        || isNaN(args[1].toNumber(exec))
        || (numArgs >= 3 && isNaN(args[2].toNumber(exec)))
        || (numArgs >= 4 && isNaN(args[3].toNumber(exec)))
        || (numArgs >= 5 && isNaN(args[4].toNumber(exec)))
        || (numArgs >= 6 && isNaN(args[5].toNumber(exec)))
        || (numArgs >= 7 && isNaN(args[6].toNumber(exec)))) {
      value = NaN;
    } else {
      struct tm t;
      memset(&t, 0, sizeof(t));
      int year = args[0].toInt32(exec);
      t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
      t.tm_mon = args[1].toInt32(exec);
      t.tm_mday = (numArgs >= 3) ? args[2].toInt32(exec) : 1;
      t.tm_hour = (numArgs >= 4) ? args[3].toInt32(exec) : 0;
      t.tm_min = (numArgs >= 5) ? args[4].toInt32(exec) : 0;
      t.tm_sec = (numArgs >= 6) ? args[5].toInt32(exec) : 0;
      t.tm_isdst = -1;
      int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0;
      value = makeTime(&t, ms, false);
    }
  }

  Object proto = exec->lexicalInterpreter()->builtinDatePrototype();
  Object ret(new DateInstanceImp(proto.imp()));
  ret.setInternalValue(Number(timeClip(value)));
  return ret;
}
Example #23
0
Value RegExpProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
{
  if (!thisObj.inherits(&RegExpImp::info)) {
    if (thisObj.inherits(&RegExpPrototypeImp::info)) {
      switch (id) {
        case ToString: return String("//"); // FireFox returns /(?:)/
      }
    }
    Object err = Error::create(exec,TypeError);
    exec->setException(err);
    return err;
  }

  RegExpImp *reimp = static_cast<RegExpImp*>(thisObj.imp());
  RegExp *re = reimp->regExp();
  String s;
  UString str;
  switch (id) {
  case Exec:      // 15.10.6.2
  case Test:
  {
    s = args[0].toString(exec);
    int length = s.value().size();

    // Get values from the last time (in case of /g)
    Value lastIndex = thisObj.get(exec,"lastIndex");
    int i = lastIndex.isValid() ? lastIndex.toInt32(exec) : 0;
    bool globalFlag = thisObj.get(exec,"global").toBoolean(exec);
    if (!globalFlag)
      i = 0;
    if (i < 0 || i > length) {
      thisObj.put(exec,"lastIndex", Number(0), DontDelete | DontEnum);
      if (id == Test)
        return Boolean(false);
      else
        return Null();
    }
    RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp().imp());
    int **ovector = regExpObj->registerRegexp( re, s.value() );

    re->prepareMatch(s.value());
    str = re->match(s.value(), i, 0L, ovector);
    re->doneMatch();
    regExpObj->setSubPatterns(re->subPatterns());

    if (id == Test)
      return Boolean(!str.isNull());

    if (str.isNull()) // no match
    {
      if (globalFlag)
        thisObj.put(exec,"lastIndex",Number(0), DontDelete | DontEnum);
      return Null();
    }
    else // success
    {
      if (globalFlag)
        thisObj.put(exec,"lastIndex",Number( (*ovector)[1] ), DontDelete | DontEnum);
      return regExpObj->arrayOfMatches(exec,str);
    }
  }
  break;
  case ToString:
    s = thisObj.get(exec,"source").toString(exec);
    str = "/";
    str += s.value();
    str += "/";
    if (thisObj.get(exec,"global").toBoolean(exec)) {
      str += "g";
    }
    if (thisObj.get(exec,"ignoreCase").toBoolean(exec)) {
      str += "i";
    }
    if (thisObj.get(exec,"multiline").toBoolean(exec)) {
      str += "m";
    }
    return String(str);
  case Compile: {
      RegExp* newEngine = RegExpObjectImp::makeEngine(exec, args[0].toString(exec), args[1]);
      if (!newEngine)
        return exec->exception();
      reimp->setRegExp(newEngine);
      return Value(reimp);
    }
  }
  

  return Undefined();
}