What's up with string methods?

Nov 25, 2009 at 9:05 AM

So, normally in JavaScript, "strings" have specific methods.

I've recently found that Jint's strings have .Net's string methods, which are different from JavaScript's string methods.  (Look a few tables down:  http://www.w3schools.com/jsref/jsref_obj_string.asp)

Is this a specific feature of Jint?  Is there an intention to implement the Javascript string functions?  If I were to try to implement them, how would I go about adding them?

Nov 25, 2009 at 9:22 AM

This is a very good question ! Actually I have not completed the full implementation from ES3 specification, and thus for native classes' methods also. They are complete for the Global object and the Object class for instance. There are two different types of methods to implement: the static and instance methods.

Implementing static methods:

Take a look at Jint.Native.JsGlobal.cs constructor, more specifically at this line:

this["parseInt"] = new JsFunctionWrapper(ParseInt); // 15.1.2.2

It declares the static parseInt method, i.e. which doesn't require an instance. The following implementation is done in the same class, in C#.

This is the exact implementation of the ECMAScript specification. You can even see the reference in the document in the comment's summary: 15.1.2.2

Implementing instance methods:

Those implementations are done using the ClrImplDefinition<T> class. A good example is how I have implemented Array.push() in the class JsArrayConstructor. Those methods needs to be added in the prototype of the constructor object.

Implementing instance getters:

When you need to code a logic which is actually published as a property, you can use ClrGetterDefinition. The example is Array.length in the JsArrayConstructor.

 

With this information you should be able to implement any native method or property, only if you can't wait for me to do it.

Cheers,

Sébastien

Nov 25, 2009 at 8:58 PM

Argh...  This isn't as easy as it first appears.

I'm calling indexOf() on a string that comes from an eval('({"c":""})') JSON object.  Unfortunately, c.indexOf() looks for the indexOf() method in JsValue instead of JsString.

How and when to replace the JsValue with a JsString is something that I really don't understand, and is beyond my comfort zone.  I'm not sure how type needs to be implemented; and I'm not sure if this is something that's radically different in 0.8.6.  (I'm still at 0.8.5)

Anyway, here are the changes that I made to JsString.  I didn't get to test them, but they might be useful:

---

public JsString()
        {
            value = String.Empty;

            Prototype = new JsPrototype(null);
            Prototype["indexOf"] = new ClrImplDefinition(IndexOf);
            Prototype["length"] = new ClrGetterDefinition(GetLength);
        }

        public JsString(string str) : this()  // this makes sure that Prototype is initialized
        {
            value = str;
        }
    

---

public JsInstance IndexOf(JsDictionaryObject targetObj, JsInstance[] parameters)
        {
            // Not sure if this is the correct behavior for no parameters
            if (0 == parameters.Length)
                return new JsNumber(-1);

            string target = targetObj.ToString();

            // Can target be null?  I don't think it can happen...
            if (null == target)
                return new JsNumber(-1);

            string searchValue = parameters[0].ToString();

            int fromindex = 0;
            if (parameters.Length < 1)
                fromindex = Convert.ToInt32(parameters[1].ToNumber());

            int toReturn = target.IndexOf(searchValue, fromindex);

            return new JsNumber(toReturn);
        }

        public JsInstance GetLength(JsDictionaryObject target)
        {
            return new JsNumber(target.ToString().Length);
        }

 

Apr 24, 2011 at 7:22 AM

Has this been fixed? I still get -1 on indexOf nomatter what...

Jun 24, 2011 at 5:50 AM

Hi Alexander,

Could you give me a repro script that I can run in order to fix it ? You might also file a bug to follow the resolution.

Thanks

Feb 11, 2012 at 11:15 PM

I also noticed that JsString does not implement IComparable.  The script attempting to execute does not pass a comparer so it falls through to the default List<JsInstance>.Sort() which fails due to the unimplemented interface.  Am I wrong to expect that?

            if (compare != null) {
                try {
                    values.Sort(new JsComparer(Global.Visitor, compare));
                }
                catch (Exception e) {
                    if (e.InnerException is JsException) {
                        throw e.InnerException;
                    }

                    throw;
                }
            }
            else {
                values.Sort();
            }