gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] [SCM] Gnash branch, master, updated. f9bdf1e9b567ddfd4801


From: Benjamin Wolsey
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. f9bdf1e9b567ddfd4801d9d619d85e16370e0a9e
Date: Fri, 08 Oct 2010 09:39:26 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  f9bdf1e9b567ddfd4801d9d619d85e16370e0a9e (commit)
       via  6de513e7ad5000c8fb9c16511693e47f3fcfbcd4 (commit)
       via  32237a93e5c6218f720d7b6b3e4f38b86a8e74de (commit)
       via  a554d076eed757cb43c03c7ce1ba1e38b12f0d6d (commit)
       via  fc2ca5004aeeac3cbb2e883b569cd783ca3ee4e0 (commit)
       via  3618d5207a4476d3760af06def3c3050c6cee325 (commit)
       via  62b44d9a91944e6448cfee69c2502886d9e7133d (commit)
       via  d8ac7a62591c827a0a6a37d18580568a0a01ea1f (commit)
       via  7af4e6cc88eb803845ac826c72f53f0b50388f48 (commit)
       via  46cf89e6467bc1a96f7e7e11089f51d19d9b88e8 (commit)
       via  891a392ba637f6162b4b809ab23d7b7e649b21d8 (commit)
       via  586fdd79ab7a758fd1a7850a76fd65a2ccca1fd5 (commit)
       via  5192164c0260ca1a8ca7986274470e1bb3c9e46c (commit)
       via  76f94f4f0e97b4d5ab9fabfa98e22c562f0a8bed (commit)
       via  767fd1e85c317a56ab53b89d8c3f6909d13417fe (commit)
       via  df57ebaa3f9f28e5f243c6e5646e28ba72b03834 (commit)
       via  a26699161c963370b8bd42027120e12ee48fbc7f (commit)
       via  5ee7efe3ec5d1570edf2807f1601185e9bba4d05 (commit)
       via  b88ec353b054a013b5d533f216ca4344988a4fe9 (commit)
       via  9e0dc654e56972056eca60ab2730fe4a9b61af41 (commit)
      from  32a0a6f93c061c8fb7507305922c45cf4c34d64a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=f9bdf1e9b567ddfd4801d9d619d85e16370e0a9e


commit f9bdf1e9b567ddfd4801d9d619d85e16370e0a9e
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 11:03:16 2010 +0200

    Fix fileio.

diff --git a/extensions/fileio/fileio.cpp b/extensions/fileio/fileio.cpp
index 2aef409..3cda1ae 100644
--- a/extensions/fileio/fileio.cpp
+++ b/extensions/fileio/fileio.cpp
@@ -538,7 +538,7 @@ fileio_asyncmode(const fn_call& fn)
 //    GNASH_REPORT_FUNCTION;
     FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
     assert(ptr);
-    bool b = (bool) fn.arg(0).to_bool();
+    bool b = toBool(fn.arg(0), getVM(fn));
     return as_value(ptr->asyncmode(b));
 }
 

http://git.savannah.gnu.org/cgit//commit/?id=6de513e7ad5000c8fb9c16511693e47f3fcfbcd4


commit 6de513e7ad5000c8fb9c16511693e47f3fcfbcd4
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 10:54:09 2010 +0200

    Drop VM::get from extension.

diff --git a/extensions/gtk2/gtkext.cpp b/extensions/gtk2/gtkext.cpp
index 10ca5f6..d8bea32 100644
--- a/extensions/gtk2/gtkext.cpp
+++ b/extensions/gtk2/gtkext.cpp
@@ -105,8 +105,8 @@ generic_callback(GtkWidget * /*widget*/, gpointer data)
        cerr << "event is: \"" << event << "\"" << endl;
     }
     
-    as_value   val;
-    as_environment env(VM::get());
+    as_value val;
+    as_environment env(getVM(*as_func));
 
     fn_call::Args args;
     args += handler, event, handler;

http://git.savannah.gnu.org/cgit//commit/?id=32237a93e5c6218f720d7b6b3e4f38b86a8e74de


commit 32237a93e5c6218f720d7b6b3e4f38b86a8e74de
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 10:47:14 2010 +0200

    Don't forget to copy movie_root pointer.

diff --git a/libcore/CharacterProxy.h b/libcore/CharacterProxy.h
index bfc76d7..7a78b63 100644
--- a/libcore/CharacterProxy.h
+++ b/libcore/CharacterProxy.h
@@ -87,6 +87,7 @@ public:
                sp.checkDangling();
                _ptr = sp._ptr;
                if (!_ptr) _tgt = sp._tgt;
+        _mr = sp._mr;
                return *this;
        }
 

http://git.savannah.gnu.org/cgit//commit/?id=a554d076eed757cb43c03c7ce1ba1e38b12f0d6d


commit a554d076eed757cb43c03c7ce1ba1e38b12f0d6d
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 09:41:34 2010 +0200

    Drop unused ostream operator that used VM singleton.

diff --git a/libcore/ClassHierarchy.cpp b/libcore/ClassHierarchy.cpp
index ad169ba..58f9661 100644
--- a/libcore/ClassHierarchy.cpp
+++ b/libcore/ClassHierarchy.cpp
@@ -180,39 +180,6 @@ ClassHierarchy::declareAll(const NativeClasses& classes)
     std::for_each(classes.begin(), classes.end(), boost::bind(nf, this, _1));
 }
 
-void
-ClassHierarchy::markReachableResources() const
-{
-    // TODO
-}
-
-std::ostream&
-operator<<(std::ostream& os, const ClassHierarchy::NativeClass& c)
-{
-    string_table& st = VM::get().getStringTable();
-
-    os << "("
-        << " name:" << st.value(getName(c.uri))
-        << " version:" << c.version
-        << ")";
-
-    return os;
-}
-
-std::ostream&
-operator<<(std::ostream& os, const ClassHierarchy::ExtensionClass& c)
-{
-    string_table& st = VM::get().getStringTable();
-
-    os << "(file:" << c.file_name
-        << " init:" << c.init_name
-        << " name:" << st.value(getName(c.uri))
-        << " version:" << c.version
-        << ")";
-
-    return os;
-}
-
 } // end of namespace gnash
 
 // local Variables:
diff --git a/libcore/ClassHierarchy.h b/libcore/ClassHierarchy.h
index a35df51..da418f6 100644
--- a/libcore/ClassHierarchy.h
+++ b/libcore/ClassHierarchy.h
@@ -119,19 +119,13 @@ public:
        void declareAll(const NativeClasses& classes);
 
        /// Mark objects for garbage collector.
-       void markReachableResources() const;
+       void markReachableResources() const {}
 
 private:
        as_object* mGlobal;
        Extension* mExtension;
 };
 
-std::ostream&
-operator<<(std::ostream& os, const ClassHierarchy::NativeClass& c);
-
-std::ostream&
-operator<<(std::ostream& os, const ClassHierarchy::ExtensionClass& c);
-
 } 
 #endif 
 

http://git.savannah.gnu.org/cgit//commit/?id=fc2ca5004aeeac3cbb2e883b569cd783ca3ee4e0


commit fc2ca5004aeeac3cbb2e883b569cd783ca3ee4e0
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 09:37:50 2010 +0200

    Drop VM::get usage in as_value.

diff --git a/libcore/as_value.cpp b/libcore/as_value.cpp
index c29e93e..b4e5bbe 100644
--- a/libcore/as_value.cpp
+++ b/libcore/as_value.cpp
@@ -63,9 +63,12 @@
 namespace gnash {
 
 namespace {
-    bool objectEqualsPrimitive(const as_value& obj, const as_value& prim);
-    bool stringEqualsNumber(const as_value& str, const as_value& num);
-    bool compareBoolean(const as_value& boolean, const as_value& other);
+    bool objectEqualsPrimitive(const as_value& obj, const as_value& prim,
+            int version);
+    bool stringEqualsNumber(const as_value& str, const as_value& num,
+            int version);
+    bool compareBoolean(const as_value& boolean, const as_value& other,
+            int version);
     inline bool findMethod(as_object& obj, string_table::key m, as_value& ret);
 }
 
@@ -312,13 +315,6 @@ as_value::to_primitive(AsType hint) const
 }
 
 double
-as_value::to_number() const
-{
-    const int swfversion = VM::get().getSWFVersion();
-    return to_number(swfversion);
-}
-
-double
 as_value::to_number(const int version) const
 {
 
@@ -432,7 +428,7 @@ as_value::to_bool(const int version) const
         case STRING:
         {
             if (version >= 7) return !getStr().empty();
-            const double num = to_number();
+            const double num = to_number(version);
             return num && !isNaN(num);
         }
         case NUMBER:
@@ -546,24 +542,24 @@ as_value::set_as_object(as_object* obj)
 }
 
 bool
-as_value::equals(const as_value& v) const
+as_value::equals(const as_value& v, int version) const
 {
 
     // First compare values of the same type.
     if (_type == v._type) return equalsSameType(v);
     
     // Then compare booleans.
-    if (is_bool()) return compareBoolean(*this, v);
-    if (v.is_bool()) return compareBoolean(v, *this);
+    if (is_bool()) return compareBoolean(*this, v, version);
+    if (v.is_bool()) return compareBoolean(v, *this, version);
 
     // Then compare any other primitive, including null and undefined, with
     // an object.
     if (!is_object() && v.is_object()) {
-        return objectEqualsPrimitive(v, *this);
+        return objectEqualsPrimitive(v, *this, version);
     }
 
     if (is_object() && !v.is_object()) {
-        return objectEqualsPrimitive(*this, v);
+        return objectEqualsPrimitive(*this, v, version);
     }
 
     // Remaining null or undefined values only equate to other null or
@@ -573,8 +569,12 @@ as_value::equals(const as_value& v) const
     if (null || v_null) return null == v_null;
 
     // Now compare a number with a string.
-    if (is_number() && v.is_string()) return stringEqualsNumber(v, *this);
-    if (is_string() && v.is_number()) return stringEqualsNumber(*this, v);
+    if (is_number() && v.is_string()) {
+        return stringEqualsNumber(v, *this, version);
+    }
+    if (is_string() && v.is_number()) {
+        return stringEqualsNumber(*this, v, version);
+    }
     
     // Finally compare non-identical objects.
     as_value p = *this;
@@ -595,7 +595,7 @@ as_value::equals(const as_value& v) const
         return false;
     }
     
-    return p.equals(vp);
+    return p.equals(vp, version);
 }
     
 const char*
@@ -934,7 +934,7 @@ namespace {
 //
 /// This is a function try-block.
 bool
-objectEqualsPrimitive(const as_value& obj, const as_value& prim)
+objectEqualsPrimitive(const as_value& obj, const as_value& prim, int version)
 try {
 
     assert(obj.is_object());
@@ -942,7 +942,7 @@ try {
 
     as_value tmp = obj.to_primitive(as_value::NUMBER);
     if (obj.strictly_equals(tmp)) return false;
-    return tmp.equals(prim);
+    return tmp.equals(prim, version);
 }
 catch (const ActionTypeError&) {
     return false;
@@ -951,18 +951,18 @@ catch (const ActionTypeError&) {
 /// @param boolean      A boolean as_value
 /// @param other        An as_value of any type.
 bool
-compareBoolean(const as_value& boolean, const as_value& other)
+compareBoolean(const as_value& boolean, const as_value& other, int version)
 {
     assert(boolean.is_bool());
-    return as_value(boolean.to_number()).equals(other); 
+    return as_value(boolean.to_number(version)).equals(other, version); 
 }
 
 bool
-stringEqualsNumber(const as_value& str, const as_value& num)
+stringEqualsNumber(const as_value& str, const as_value& num, int version)
 {
     assert(num.is_number());
     assert(str.is_string());
-    const double n = str.to_number();
+    const double n = str.to_number(version);
     if (!isFinite(n)) return false;
     return num.strictly_equals(n);
 }
diff --git a/libcore/as_value.h b/libcore/as_value.h
index ba4a9e9..8d41b4c 100644
--- a/libcore/as_value.h
+++ b/libcore/as_value.h
@@ -235,7 +235,6 @@ public:
     /// Get a number representation for this value
     //
     /// This function performs conversion if necessary.
-    double to_number() const;
     double to_number(int version) const;
     
     /// Conversion to boolean.
@@ -375,7 +374,7 @@ public:
     ///          evaluation of A and B.
     ///
     /// @param v     The as_value to compare to
-    bool equals(const as_value& v) const;
+    bool equals(const as_value& v, int version) const;
     
     /// Set any object value as reachable (for the GC)
     //
diff --git a/libcore/asobj/AsBroadcaster.cpp b/libcore/asobj/AsBroadcaster.cpp
index c2438ce..89bfc91 100644
--- a/libcore/asobj/AsBroadcaster.cpp
+++ b/libcore/asobj/AsBroadcaster.cpp
@@ -367,7 +367,7 @@ asbroadcaster_removeListener(const fn_call& fn)
         std::ostringstream s;
         s << i;
         as_value el = getMember(*listeners, st.find(s.str()));
-        if (el.equals(listenerToRemove)) {
+        if (equals(el, listenerToRemove, getVM(fn))) {
             callMethod(listeners, NSV::PROP_SPLICE, s.str(), 1);
             return as_value(true);
         }
diff --git a/libcore/asobj/flash/geom/Point_as.cpp 
b/libcore/asobj/flash/geom/Point_as.cpp
index aa9a2ac..9173c0d 100644
--- a/libcore/asobj/flash/geom/Point_as.cpp
+++ b/libcore/asobj/flash/geom/Point_as.cpp
@@ -220,7 +220,7 @@ point_equals(const fn_call& fn)
     o->get_member(NSV::PROP_X, &x1);
     o->get_member(NSV::PROP_Y, &y1);
 
-    return as_value(x.equals(x1) && y.equals(y1));
+    return as_value(equals(x, x1, getVM(fn)) && equals(y, y1, getVM(fn)));
 }
 
 as_value
diff --git a/libcore/vm/ASHandlers.cpp b/libcore/vm/ASHandlers.cpp
index 5e76efa..8934081 100644
--- a/libcore/vm/ASHandlers.cpp
+++ b/libcore/vm/ASHandlers.cpp
@@ -2649,12 +2649,12 @@ ActionNewEquals(ActionExec& thread)
                     op2, e.what());
         }
 
-        env.top(1).set_bool(op1.equals(op2));
+        env.top(1).set_bool(equals(op1, op2, getVM(env)));
     }
     else
     {
         /// ECMA-262 abstract equality comparison (sect 11.9.3)
-        env.top(1).set_bool(env.top(1).equals(env.top(0)));
+        env.top(1).set_bool(equals(env.top(1), env.top(0), getVM(env)));
     }
     env.drop(1);
 }
@@ -3197,7 +3197,6 @@ ActionShiftRight2(ActionExec& thread)
 void
 ActionStrictEq(ActionExec& thread)
 {
-    
     as_environment& env = thread.env;
     
     env.top(1).set_bool(env.top(1).strictly_equals(env.top(0)));
diff --git a/libcore/vm/VM.cpp b/libcore/vm/VM.cpp
index 7f906b6..64650f1 100644
--- a/libcore/vm/VM.cpp
+++ b/libcore/vm/VM.cpp
@@ -507,6 +507,12 @@ newLessThan(const as_value& op1, const as_value& op2, 
const VM& vm)
 }
 
 bool
+equals(const as_value& a, const as_value& b, const VM& vm)
+{
+    return a.equals(b, vm.getSWFVersion());
+}
+
+bool
 toBool(const as_value& v, const VM& vm)
 {
     return v.to_bool(vm.getSWFVersion());
diff --git a/libcore/vm/VM.h b/libcore/vm/VM.h
index d5c5dfe..27898de 100644
--- a/libcore/vm/VM.h
+++ b/libcore/vm/VM.h
@@ -425,6 +425,8 @@ void subtract(as_value& op1, const as_value& op2, const VM& 
vm);
 /// @param vm       The VM executing the operation.
 as_value newLessThan(const as_value& op1, const as_value& op2, const VM& vm);
 
+bool equals(const as_value& a, const as_value& b, const VM& vm);
+
 /// Convert an as_value to boolean type
 bool toBool(const as_value& v, const VM& vm);
 

http://git.savannah.gnu.org/cgit//commit/?id=3618d5207a4476d3760af06def3c3050c6cee325


commit 3618d5207a4476d3760af06def3c3050c6cee325
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 09:20:05 2010 +0200

    Fix testsuite

diff --git a/testsuite/misc-ming.all/attachMovieTestRunner.cpp 
b/testsuite/misc-ming.all/attachMovieTestRunner.cpp
index 59662bc..d75f4be 100644
--- a/testsuite/misc-ming.all/attachMovieTestRunner.cpp
+++ b/testsuite/misc-ming.all/attachMovieTestRunner.cpp
@@ -79,6 +79,8 @@ main(int /*argc*/, char** /*argv*/)
        // check that the pixel under the mouse is white
        check_pixel(100, 30, 2, rgba(255,255,255,255), 2);
 
+    VM& vm = VM::get();
+
        string_table& st = VM::get().getStringTable();
 
        getObject(root)->get_member(st.find("mousedown"), &tmp);
@@ -90,15 +92,15 @@ main(int /*argc*/, char** /*argv*/)
        tester.pressMouseButton();
 
        getObject(root)->get_member(st.find("mousedown"), &tmp);
-       check_equals(tmp.to_number(), 1);
+       check_equals(toNumber(tmp, vm), 1);
        check ( ! getObject(root)->get_member(st.find("mouseup"), &tmp) );
 
        tester.depressMouseButton();
 
        getObject(root)->get_member(st.find("mousedown"), &tmp);
-       check_equals(tmp.to_number(), 1);
+       check_equals(toNumber(tmp, vm), 1);
        getObject(root)->get_member(st.find("mouseup"), &tmp);
-       check_equals(tmp.to_number(), 1);
+       check_equals(toNumber(tmp, vm), 1);
 
        tester.advance();
 
@@ -155,7 +157,7 @@ main(int /*argc*/, char** /*argv*/)
        tester.pressMouseButton();
 
        getObject(root)->get_member(st.find("mousedown"), &tmp);
-       check_equals(tmp.to_number(), 5);
+       check_equals(toNumber(tmp, vm), 5);
 
 }
 
diff --git a/testsuite/misc-ming.all/intervalTestRunner.cpp 
b/testsuite/misc-ming.all/intervalTestRunner.cpp
index 5dffe16..7fc62fb 100644
--- a/testsuite/misc-ming.all/intervalTestRunner.cpp
+++ b/testsuite/misc-ming.all/intervalTestRunner.cpp
@@ -64,65 +64,65 @@ main(int /*argc*/, char** /*argv*/)
        VM& vm = VM::get();
        string_table& st = vm.getStringTable();
        getObject(root)->get_member(st.find("this_counter"), &tmp);
-       check_equals(tmp.to_number(), 0);
+       check_equals(toNumber(tmp, vm), 0);
        getObject(root)->get_member(st.find("that_counter"), &tmp);
-       check_equals(tmp.to_number(), 0);
+       check_equals(toNumber(tmp, vm), 0);
 
        tester.advanceClock(500); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
        getObject(root)->get_member(st.find("this_counter"), &tmp);
-       check_equals(tmp.to_number(), 1);
+       check_equals(toNumber(tmp, vm), 1);
        getObject(root)->get_member(st.find("that_counter"), &tmp);
-       check_equals(tmp.to_number(), 0);
+       check_equals(toNumber(tmp, vm), 0);
 
        tester.advanceClock(600); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
        getObject(root)->get_member(st.find("this_counter"), &tmp);
-       check_equals(tmp.to_number(), 2);
+       check_equals(toNumber(tmp, vm), 2);
        getObject(root)->get_member(st.find("that_counter"), &tmp);
-       check_equals(tmp.to_number(), 1);
+       check_equals(toNumber(tmp, vm), 1);
 
        tester.advanceClock(500); // "sleep" 500 milliseconds
        tester.advance(); // run expired timers
 
        getObject(root)->get_member(st.find("this_counter"), &tmp);
-       check_equals(tmp.to_number(), 3);
+       check_equals(toNumber(tmp, vm), 3);
        getObject(root)->get_member(st.find("that_counter"), &tmp);
-       check_equals(tmp.to_number(), 1);
+       check_equals(toNumber(tmp, vm), 1);
 
        tester.advanceClock(520); // "sleep" 520 milliseconds
        tester.advance(); // run expired timers
 
        getObject(root)->get_member(st.find("this_counter"), &tmp);
-       check_equals(tmp.to_number(), 4);
+       check_equals(toNumber(tmp, vm), 4);
        getObject(root)->get_member(st.find("that_counter"), &tmp);
-       check_equals(tmp.to_number(), 2);
+       check_equals(toNumber(tmp, vm), 2);
 
        tester.advanceClock(1020); // "sleep" 1020 milliseconds
        tester.advance(); // run expired timers
 
        getObject(root)->get_member(st.find("this_counter"), &tmp);
-       check_equals(tmp.to_number(), 4);
+       check_equals(toNumber(tmp, vm), 4);
        getObject(root)->get_member(st.find("that_counter"), &tmp);
-       check_equals(tmp.to_number(), 3);
+       check_equals(toNumber(tmp, vm), 3);
 
        tester.advanceClock(1020); // "sleep" 1020 milliseconds
        tester.advance(); // run expired timers
 
        getObject(root)->get_member(st.find("this_counter"), &tmp);
-       check_equals(tmp.to_number(), 4);
+       check_equals(toNumber(tmp, vm), 4);
        getObject(root)->get_member(st.find("that_counter"), &tmp);
-       check_equals(tmp.to_number(), 4);
+       check_equals(toNumber(tmp, vm), 4);
 
        tester.advanceClock(520); // "sleep" 520 milliseconds
        tester.advance(); // run expired timers
 
        getObject(root)->get_member(st.find("this_counter"), &tmp);
-       check_equals(tmp.to_number(), 5);
+       check_equals(toNumber(tmp, vm), 5);
        getObject(root)->get_member(st.find("that_counter"), &tmp);
-       check_equals(tmp.to_number(), 4);
+       check_equals(toNumber(tmp, vm), 4);
 
        getObject(root)->get_member(st.find("pushed_args"), &tmp);
        as_environment env(vm); // needed for proper to_string()
@@ -132,7 +132,7 @@ main(int /*argc*/, char** /*argv*/)
        tester.advance(); // run expired timers
 
        getObject(root)->get_member(st.find("test_completed"), &tmp);
-       check_equals(tmp.to_number(), 1);
+       check_equals(toNumber(tmp, vm), 1);
 
 
 }
diff --git a/testsuite/movies.all/gravity_embedded-TestRunner.cpp 
b/testsuite/movies.all/gravity_embedded-TestRunner.cpp
index 53dd62c..c65b58b 100644
--- a/testsuite/movies.all/gravity_embedded-TestRunner.cpp
+++ b/testsuite/movies.all/gravity_embedded-TestRunner.cpp
@@ -68,6 +68,8 @@ main(int /*argc*/, char** /*argv*/)
        check(loaded);
        check_equals(loaded->parent(), root);
 
+    VM& vm = VM::get();
+
        string_table& st = VM::get().getStringTable();
        string_table::key xscale = st.find("_xscale");
        string_table::key yscale = st.find("_yscale");
@@ -97,25 +99,25 @@ main(int /*argc*/, char** /*argv*/)
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "48");
        check(obj->get_member(xscale, &tmp));
-       check_equals(round(tmp.to_number()), 48);
+       check_equals(round(toNumber(tmp, vm)), 48);
        check(obj->get_member(yscale, &tmp));
-       check_equals(round(tmp.to_number()), 48);
+       check_equals(round(toNumber(tmp, vm)), 48);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "48");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "46");
        check(obj->get_member(xscale, &tmp));
-       check_equals(round(tmp.to_number()), 46);
+       check_equals(round(toNumber(tmp, vm)), 46);
        check(obj->get_member(yscale, &tmp));
-       check_equals(round(tmp.to_number()), 46);
+       check_equals(round(toNumber(tmp, vm)), 46);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "46");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "44");
        check(obj->get_member(xscale, &tmp));
-       check_equals(round(tmp.to_number()), 44);
+       check_equals(round(toNumber(tmp, vm)), 44);
        check(obj->get_member(yscale, &tmp));
-       check_equals(round(tmp.to_number()), 44);
+       check_equals(round(toNumber(tmp, vm)), 44);
 
        // click some on the "larger" button
        tester.movePointerTo(580, 18);
@@ -125,33 +127,33 @@ main(int /*argc*/, char** /*argv*/)
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "46");
        check(obj->get_member(xscale, &tmp));
-       check_equals(round(tmp.to_number()), 46);
+       check_equals(round(toNumber(tmp, vm)), 46);
        check(obj->get_member(yscale, &tmp));
-       check_equals(round(tmp.to_number()), 46);
+       check_equals(round(toNumber(tmp, vm)), 46);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "46");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "48");
        check(obj->get_member(xscale, &tmp));
-       check_equals(round(tmp.to_number()), 48);
+       check_equals(round(toNumber(tmp, vm)), 48);
        check(obj->get_member(yscale, &tmp));
-       check_equals(round(tmp.to_number()), 48);
+       check_equals(round(toNumber(tmp, vm)), 48);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "48");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "50");
        check(obj->get_member(xscale, &tmp));
-       check_equals(round(tmp.to_number()), 50);
+       check_equals(round(toNumber(tmp, vm)), 50);
        check(obj->get_member(yscale, &tmp));
-       check_equals(round(tmp.to_number()), 50);
+       check_equals(round(toNumber(tmp, vm)), 50);
        tester.pressMouseButton();
        check_equals(string(text->get_text_value()), "50");
        tester.depressMouseButton();
        check_equals(string(text->get_text_value()), "52");
        check(obj->get_member(xscale, &tmp));
-       check_equals(round(tmp.to_number()), 52);
+       check_equals(round(toNumber(tmp, vm)), 52);
        check(obj->get_member(yscale, &tmp));
-       check_equals(round(tmp.to_number()), 52);
+       check_equals(round(toNumber(tmp, vm)), 52);
 
 
 }

http://git.savannah.gnu.org/cgit//commit/?id=62b44d9a91944e6448cfee69c2502886d9e7133d


commit 62b44d9a91944e6448cfee69c2502886d9e7133d
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 09:07:36 2010 +0200

    Use new toInt, drop remaining to_number().

diff --git a/libcore/as_value.cpp b/libcore/as_value.cpp
index 92bf8bb..c29e93e 100644
--- a/libcore/as_value.cpp
+++ b/libcore/as_value.cpp
@@ -67,7 +67,6 @@ namespace {
     bool stringEqualsNumber(const as_value& str, const as_value& num);
     bool compareBoolean(const as_value& boolean, const as_value& other);
     inline bool findMethod(as_object& obj, string_table::key m, as_value& ret);
-    boost::int32_t truncateToInt(double d);
 }
 
 namespace {
@@ -780,17 +779,6 @@ as_value::writeAMF0(amf::Writer& w) const
     }
 }
 
-
-boost::int32_t
-toInt(const as_value& val) 
-{
-    const double d = val.to_number();
-
-    if (!isFinite(d)) return 0;
-
-    return truncateToInt(d);
-}
-
 bool
 parseNonDecimalInt(const std::string& s, double& d, bool whole)
 {
@@ -987,22 +975,6 @@ findMethod(as_object& obj, string_table::key m, as_value& 
ret)
     return obj.get_member(m, &ret) && ret.is_object();
 }
 
-/// Truncates a double to a 32-bit unsigned int.
-//
-/// In fact, it is a 32-bit unsigned int with an additional sign, cast
-/// to an unsigned int. Not sure what the sense is, but that's how it works:
-//
-/// 0xffffffff is interpreted as -1, -0xffffffff as 1.
-boost::int32_t
-truncateToInt(double d)
-{
-    if (d < 0) {   
-        return - static_cast<boost::uint32_t>(std::fmod(-d, 4294967296.0));
-    }
-    
-    return static_cast<boost::uint32_t>(std::fmod(d, 4294967296.0));
-}
-
 } // unnamed namespace
 
 std::ostream&
diff --git a/libcore/as_value.h b/libcore/as_value.h
index f04a471..ba4a9e9 100644
--- a/libcore/as_value.h
+++ b/libcore/as_value.h
@@ -511,15 +511,6 @@ std::string doubleToString(double val, int radix = 10);
 ///               parsed.
 bool parseNonDecimalInt(const std::string& s, double& d, bool whole = true);
 
-/// AS2-compatible conversion to 32bit integer
-//
-/// This truncates large numbers to fit in the 32-bit space. It is not a 
-/// proper function of as_value because it is simply a further operation on
-/// the stored number type.
-//
-/// This function calls to_number(), so performs a conversion if necessary.
-boost::int32_t toInt(const as_value& val);
-
 /// Set a value to NaN
 inline void
 setNaN(as_value& v) {
diff --git a/libcore/asobj/Array_as.cpp b/libcore/asobj/Array_as.cpp
index ce4cba8..5a982e4 100644
--- a/libcore/asobj/Array_as.cpp
+++ b/libcore/asobj/Array_as.cpp
@@ -600,7 +600,7 @@ public:
         args += b, a;
         ret = invoke(cmp_method, _env, _object, args);
 
-        return (*_zeroCmp)(toInt(ret));
+        return (*_zeroCmp)(toInt(ret, getVM(_env)));
     }
 };
 
@@ -764,23 +764,26 @@ private:
 class GetMultiFlags
 {
 public:
-    GetMultiFlags(std::vector<boost::uint8_t>& v)
+    GetMultiFlags(std::vector<boost::uint8_t>& v, const fn_call& fn)
         :
         _v(v),
         _i(0),
         _uniq(false),
-        _index(false)
+        _index(false),
+        _fn(fn)
     {}
     void operator()(const as_value& val) {
         // extract SORT_UNIQUE and SORT_RETURN_INDEX from first flag
         if (!_i) {
-            boost::uint8_t flag = static_cast<boost::uint8_t>(val.to_number());
+            boost::uint8_t flag =
+                static_cast<boost::uint8_t>(toNumber(val, getVM(_fn)));
             flag = flag_preprocess(flag, &_uniq, &_index);
             _v.push_back(flag);
             ++_i;
             return;
         }
-        boost::uint8_t flag = static_cast<boost::uint8_t>(val.to_number());
+        boost::uint8_t flag = 
+                static_cast<boost::uint8_t>(toNumber(val, getVM(_fn)));
         flag &= ~(SORT_RETURN_INDEX);
         flag &= ~(SORT_UNIQUE);
         _v.push_back(flag);
@@ -794,6 +797,7 @@ private:
     size_t _i;
     bool _uniq;
     bool _index;
+    const fn_call& _fn;
 };
 
 }
@@ -812,7 +816,7 @@ checkArrayLength(as_object& array, const ObjectURI& uri, 
const as_value& val)
 {
     const string_table::key name = getName(uri);
     if (name == NSV::PROP_LENGTH) {
-        resizeArray(array, toInt(val));
+        resizeArray(array, toInt(val, getVM(array)));
         return;
     }
 
@@ -833,7 +837,7 @@ arrayLength(as_object& array)
     const as_value& length = getOwnProperty(array, NSV::PROP_LENGTH);
     if (length.is_undefined()) return 0;
     
-    const int size = toInt(length);
+    const int size = toInt(length, getVM(array));
     if (size < 0) return 0;
     return size;
 }
@@ -937,7 +941,7 @@ array_splice(const fn_call& fn)
     // Get start offset
     //----------------
 
-    int start = toInt(fn.arg(0));
+    int start = toInt(fn.arg(0), getVM(fn));
     if (start < 0) start = size + start; 
     start = clamp<int>(start, 0, size);
 
@@ -945,7 +949,7 @@ array_splice(const fn_call& fn)
     size_t remove = size - start;
     
     if (fn.nargs > 1) {
-        int remval = toInt(fn.arg(1));
+        int remval = toInt(fn.arg(1), getVM(fn));
         if (remval < 0) {
             IF_VERBOSE_ASCODING_ERRORS(
                 log_aserror(_("Array.splice(%d,%d): negative length "
@@ -1137,7 +1141,7 @@ array_sortOn(const fn_call& fn)
             if (farray->array() && arrayLength(*farray) == optnum) {
 
                 std::vector<boost::uint8_t> flgs;
-                GetMultiFlags mf(flgs);
+                GetMultiFlags mf(flgs, fn);
                 foreachArray(*farray, mf);
                 do_unique = mf.unique();
                 do_index = mf.index();
@@ -1163,7 +1167,7 @@ array_sortOn(const fn_call& fn)
         // case: sortOn(["prop1", "prop2"], Array.FLAG)
         else {
             boost::uint8_t flags = 
-                static_cast<boost::uint8_t>(toInt(fn.arg(1)));
+                static_cast<boost::uint8_t>(toInt(fn.arg(1), getVM(fn)));
             flags = flag_preprocess(flags, &do_unique, &do_index);
             as_cmp_fn c = get_basic_cmp(flags, fn);
 
@@ -1384,10 +1388,10 @@ array_slice(const fn_call& fn)
         );
     }
 
-    int startindex = fn.nargs ? toInt(fn.arg(0)) : 0;
+    int startindex = fn.nargs ? toInt(fn.arg(0), getVM(fn)) : 0;
 
     // if we sent at least two arguments, setup endindex
-    int endindex = fn.nargs > 1 ? toInt(fn.arg(1)) :
+    int endindex = fn.nargs > 1 ? toInt(fn.arg(1), getVM(fn)) :
         std::numeric_limits<int>::max();
 
     Global_as& gl = getGlobal(fn);
@@ -1417,7 +1421,7 @@ array_new(const fn_call& fn)
     }
 
     if (fn.nargs == 1 && fn.arg(0).is_number()) {
-        int newSize = toInt(fn.arg(0));
+        int newSize = toInt(fn.arg(0), getVM(fn));
         if (newSize < 0) newSize = 0;
         else {
             ao->set_member(NSV::PROP_LENGTH, newSize);
diff --git a/libcore/asobj/AsBroadcaster.cpp b/libcore/asobj/AsBroadcaster.cpp
index 92053db..c2438ce 100644
--- a/libcore/asobj/AsBroadcaster.cpp
+++ b/libcore/asobj/AsBroadcaster.cpp
@@ -358,7 +358,8 @@ asbroadcaster_removeListener(const fn_call& fn)
     
     // This is an ActionScript-like implementation, which is why it looks
     // like poor C++.
-    const int length = toInt(getMember(*listeners, NSV::PROP_LENGTH));
+    const int length = toInt(getMember(*listeners, NSV::PROP_LENGTH),
+            getVM(fn));
     int i = 0;
     string_table& st = getStringTable(fn);
 
diff --git a/libcore/asobj/Color_as.cpp b/libcore/asobj/Color_as.cpp
index 53cb837..6599615 100644
--- a/libcore/asobj/Color_as.cpp
+++ b/libcore/asobj/Color_as.cpp
@@ -160,7 +160,7 @@ color_setrgb(const fn_call& fn)
     MovieClip* sp = getTarget(obj, fn);
     if (!sp) return as_value();
 
-       boost::int32_t color = toInt(fn.arg(0));
+       boost::int32_t color = toInt(fn.arg(0), getVM(fn));
 
        const int r = (color & 0xff0000) >> 16;
        const int g = (color & 0x00ff00) >> 8;
diff --git a/libcore/asobj/Date_as.cpp b/libcore/asobj/Date_as.cpp
index c37232e..0ac5f57 100644
--- a/libcore/asobj/Date_as.cpp
+++ b/libcore/asobj/Date_as.cpp
@@ -446,9 +446,9 @@ date_new(const fn_call& fn)
         gt.minute = 0;
         gt.hour = 0;
         gt.monthday = 1;
-        gt.month = toInt(fn.arg(1));
+        gt.month = toInt(fn.arg(1), getVM(fn));
     
-        int year = toInt(fn.arg(0));
+        int year = toInt(fn.arg(0), getVM(fn));
         
         // GnashTime.year is the value since 1900 (like struct tm)
         // negative value is a year before 1900. A year between 0
@@ -467,15 +467,15 @@ date_new(const fn_call& fn)
                 )
             case 7:
                 // fractions of milliseconds are ignored
-                gt.millisecond = toInt(fn.arg(6));
+                gt.millisecond = toInt(fn.arg(6), getVM(fn));
             case 6:
-                gt.second = toInt(fn.arg(5));
+                gt.second = toInt(fn.arg(5), getVM(fn));
             case 5:
-                gt.minute = toInt(fn.arg(4));
+                gt.minute = toInt(fn.arg(4), getVM(fn));
             case 4:
-                gt.hour = toInt(fn.arg(3));
+                gt.hour = toInt(fn.arg(3), getVM(fn));
             case 3:
-                gt.monthday = toInt(fn.arg(2));
+                gt.monthday = toInt(fn.arg(2), getVM(fn));
             case 2:
                 break;
                 // Done already
@@ -843,9 +843,9 @@ date_setfullyear(const fn_call& fn)
     else {
         GnashTime gt;
         dateToGnashTime(*date, gt, utc);
-        gt.year = toInt(fn.arg(0)) - 1900;
-        if (fn.nargs >= 2) gt.month = toInt(fn.arg(1));
-        if (fn.nargs >= 3) gt.monthday = toInt(fn.arg(2));
+        gt.year = toInt(fn.arg(0), getVM(fn)) - 1900;
+        if (fn.nargs >= 2) gt.month = toInt(fn.arg(1), getVM(fn));
+        if (fn.nargs >= 3) gt.monthday = toInt(fn.arg(2), getVM(fn));
         gnashTimeToDate(gt, *date, utc);
   }
   return as_value(date->getTimeValue());
@@ -892,8 +892,8 @@ date_setYear(const fn_call& fn)
 
         truncateDouble(gt.year, year);
 
-        if (fn.nargs >= 2) gt.month = toInt(fn.arg(1));
-        if (fn.nargs >= 3) gt.monthday = toInt(fn.arg(2));
+        if (fn.nargs >= 2) gt.month = toInt(fn.arg(1), getVM(fn));
+        if (fn.nargs >= 3) gt.monthday = toInt(fn.arg(2), getVM(fn));
         if (fn.nargs > 3) {
             IF_VERBOSE_ASCODING_ERRORS(
                 log_aserror(_("Date.setYear was called with more than three "
@@ -991,7 +991,7 @@ date_setDate(const fn_call& fn)
     GnashTime gt;
 
     dateToGnashTime(*date, gt, utc);
-    gt.monthday = toInt(fn.arg(0));
+    gt.monthday = toInt(fn.arg(0), getVM(fn));
     gnashTimeToDate(gt, *date, utc);
   }
   if (fn.nargs > 1) {
@@ -1036,10 +1036,10 @@ date_setHours(const fn_call& fn)
         GnashTime gt;
 
         dateToGnashTime(*date, gt, utc);
-        gt.hour = toInt(fn.arg(0));
-        if (fn.nargs >= 2) gt.minute = toInt(fn.arg(1));
-        if (fn.nargs >= 3) gt.second = toInt(fn.arg(2));
-        if (fn.nargs >= 4) gt.millisecond = toInt(fn.arg(3));
+        gt.hour = toInt(fn.arg(0), getVM(fn));
+        if (fn.nargs >= 2) gt.minute = toInt(fn.arg(1), getVM(fn));
+        if (fn.nargs >= 3) gt.second = toInt(fn.arg(2), getVM(fn));
+        if (fn.nargs >= 4) gt.millisecond = toInt(fn.arg(3), getVM(fn));
         if (fn.nargs > 4) {
             IF_VERBOSE_ASCODING_ERRORS(
                 log_aserror(_("Date.set%sHours was called with more than "
@@ -1081,9 +1081,9 @@ date_setMinutes(const fn_call& fn)
         GnashTime gt;
 
         dateToGnashTime(*date, gt, utc);
-        gt.minute = toInt(fn.arg(0));
-        if (fn.nargs >= 2) gt.second = toInt(fn.arg(1));
-        if (fn.nargs >= 3) gt.millisecond = toInt(fn.arg(2));
+        gt.minute = toInt(fn.arg(0), getVM(fn));
+        if (fn.nargs >= 2) gt.second = toInt(fn.arg(1), getVM(fn));
+        if (fn.nargs >= 3) gt.millisecond = toInt(fn.arg(2), getVM(fn));
         if (fn.nargs > 3) {
             IF_VERBOSE_ASCODING_ERRORS(
                 log_aserror(_("Date.set%sMinutes was called with more than "
@@ -1125,8 +1125,8 @@ date_setSeconds(const fn_call& fn)
         GnashTime gt;
 
         dateToGnashTime(*date, gt, utc);
-        gt.second = toInt(fn.arg(0));
-        if (fn.nargs >= 2) gt.millisecond = toInt(fn.arg(1));
+        gt.second = toInt(fn.arg(0), getVM(fn));
+        if (fn.nargs >= 2) gt.millisecond = toInt(fn.arg(1), getVM(fn));
         if (fn.nargs > 2) {
             IF_VERBOSE_ASCODING_ERRORS(
                 log_aserror(_("Date.set%sMinutes was called with more than "
@@ -1254,17 +1254,17 @@ date_UTC(const fn_call& fn) {
             )
         case 7:
             // millisecs is double, but fractions of millisecs are ignored.
-            gt.millisecond = toInt(fn.arg(6));
+            gt.millisecond = toInt(fn.arg(6), getVM(fn));
         case 6:
-            gt.second = toInt(fn.arg(5));
+            gt.second = toInt(fn.arg(5), getVM(fn));
         case 5:
-            gt.minute = toInt(fn.arg(4));
+            gt.minute = toInt(fn.arg(4), getVM(fn));
         case 4:
-            gt.hour = toInt(fn.arg(3));
+            gt.hour = toInt(fn.arg(3), getVM(fn));
         case 3:
-            gt.monthday = toInt(fn.arg(2));
+            gt.monthday = toInt(fn.arg(2), getVM(fn));
         case 2:   // these last two are always performed
-            gt.month = toInt(fn.arg(1));
+            gt.month = toInt(fn.arg(1), getVM(fn));
             {
                 boost::int32_t year = 0;
                 truncateDouble(year, toNumber(fn.arg(0), getVM(fn)));
diff --git a/libcore/asobj/Global_as.cpp b/libcore/asobj/Global_as.cpp
index ee845c7..4e58535 100644
--- a/libcore/asobj/Global_as.cpp
+++ b/libcore/asobj/Global_as.cpp
@@ -560,7 +560,7 @@ global_parseint(const fn_call& fn)
     size_t base;
     if (fn.nargs > 1)
     {
-        base = toInt(fn.arg(1));
+        base = toInt(fn.arg(1), getVM(fn));
     
         // Bases from 2 to 36 are valid, otherwise return NaN
         if (base < 2 || base > 36) return as_value(NaN);
@@ -691,7 +691,7 @@ global_assetpropflags(const fn_call& fn)
 
     // ASSetPropFlags was exposed in Flash 5, however the fourth argument
     // 'set_false' was not required as it always defaulted to the value '~0'. 
-    const int setFalse = (fn.nargs < 4 ? 0 : toInt(fn.arg(3))) &
+    const int setFalse = (fn.nargs < 4 ? 0 : toInt(fn.arg(3), getVM(fn))) &
         flagsMask;
 
     obj->setPropFlags(props, setFalse, setTrue);
@@ -714,8 +714,8 @@ global_asconstructor(const fn_call& fn)
         return as_value();
     }
 
-    const int sx = toInt(fn.arg(0));
-    const int sy = toInt(fn.arg(1));
+    const int sx = toInt(fn.arg(0), getVM(fn));
+    const int sy = toInt(fn.arg(1), getVM(fn));
 
     if (sx < 0 || sy < 0) {
         IF_VERBOSE_ASCODING_ERRORS(    
@@ -759,8 +759,8 @@ global_asnative(const fn_call& fn)
         return as_value();
     }
 
-    const int sx = toInt(fn.arg(0));
-    const int sy = toInt(fn.arg(1));
+    const int sx = toInt(fn.arg(0), getVM(fn));
+    const int sy = toInt(fn.arg(1), getVM(fn));
 
     if (sx < 0 || sy < 0) {
         IF_VERBOSE_ASCODING_ERRORS(    
@@ -813,12 +813,12 @@ global_assetnative(const fn_call& fn)
         return as_value();
     }
 
-    const int major = toInt(fn.arg(1));
+    const int major = toInt(fn.arg(1), getVM(fn));
     if (major < 0) return as_value();
 
     const std::string& props = fn.arg(2).to_string();
     const int minor =
-        fn.nargs > 3 ? std::max<boost::int32_t>(toInt(fn.arg(3)), 0) : 0;
+        fn.nargs > 3 ? std::max<boost::int32_t>(toInt(fn.arg(3), getVM(fn)), 
0) : 0;
 
     std::string::const_iterator pos = props.begin();
 
@@ -884,12 +884,12 @@ global_assetnativeaccessor(const fn_call& fn)
         return as_value();
     }
 
-    const int major = toInt(fn.arg(1));
+    const int major = toInt(fn.arg(1), getVM(fn));
     if (major < 0) return as_value();
 
     const std::string& props = fn.arg(2).to_string();
     const int minor =
-        fn.nargs > 3 ? std::max<boost::int32_t>(toInt(fn.arg(3)), 0) : 0;
+        fn.nargs > 3 ? std::max<boost::int32_t>(toInt(fn.arg(3), getVM(fn)), 
0) : 0;
 
     std::string::const_iterator pos = props.begin();
 
diff --git a/libcore/asobj/Key_as.cpp b/libcore/asobj/Key_as.cpp
index 263107b..efa9dab 100644
--- a/libcore/asobj/Key_as.cpp
+++ b/libcore/asobj/Key_as.cpp
@@ -74,7 +74,7 @@ key_is_down(const fn_call& fn)
         return as_value();
     }
 
-    const int keycode = toInt(fn.arg(0));
+    const int keycode = toInt(fn.arg(0), getVM(fn));
     if (keycode < 0 || keycode >= key::KEYCOUNT) {
         // AS coding error !
         IF_VERBOSE_ASCODING_ERRORS(
diff --git a/libcore/asobj/LocalConnection_as.cpp 
b/libcore/asobj/LocalConnection_as.cpp
index 4e6f1df..521fcb8 100644
--- a/libcore/asobj/LocalConnection_as.cpp
+++ b/libcore/asobj/LocalConnection_as.cpp
@@ -867,12 +867,11 @@ executeAMFFunction(as_object& o, amf::Reader& rd)
         if (rd(a)) log_debug("First Number: %s", a);
 
         // Handle negative numbers.
-        const size_t count = std::max<int>(0, toInt(a));
+        const size_t count = std::max<int>(0, toInt(a, getVM(o)));
 
         // We don't know what the second number signifies.
         if (rd(a)) log_debug("Second Number: %s", a);
 
-
         for (size_t i = 0; i < count; ++i) {
             if (!rd(a)) {
                 log_error("Fewer AMF fields than expected.");
diff --git a/libcore/asobj/Microphone_as.cpp b/libcore/asobj/Microphone_as.cpp
index 0c0ff2c..af5c3b0 100644
--- a/libcore/asobj/Microphone_as.cpp
+++ b/libcore/asobj/Microphone_as.cpp
@@ -294,7 +294,7 @@ microphone_setgain(const fn_call& fn)
         return as_value();
     } 
 
-    const boost::int32_t gain = clamp<boost::int32_t>(toInt(fn.arg(0)), 0, 
100);
+    const boost::int32_t gain = clamp<boost::int32_t>(toInt(fn.arg(0), 
getVM(fn)), 0, 100);
     ptr->setGain(gain);
     return as_value();
 }
@@ -309,7 +309,7 @@ microphone_setrate(const fn_call& fn)
         log_error("Microphone.setRate: wrong number of parameters passed");
         return as_value();
     }
-    ptr->setRate(toInt(fn.arg(0)));
+    ptr->setRate(toInt(fn.arg(0), getVM(fn)));
     return as_value();
 }
 
@@ -451,7 +451,7 @@ microphone_setsilencelevel(const fn_call& fn)
     
     if (numargs > 1) {
         // If it's less than 0, it's set to 0.
-        const int timeout = std::max<boost::int32_t>(toInt(fn.arg(1)), 0);
+        const int timeout = std::max<boost::int32_t>(toInt(fn.arg(1), 
getVM(fn)), 0);
         ptr->setSilenceTimeout(timeout);
     }
     return as_value();
diff --git a/libcore/asobj/MovieClip_as.cpp b/libcore/asobj/MovieClip_as.cpp
index f0b9411..c430465 100644
--- a/libcore/asobj/MovieClip_as.cpp
+++ b/libcore/asobj/MovieClip_as.cpp
@@ -319,7 +319,7 @@ movieclip_createEmptyMovieClip(const fn_call& fn)
     // Unlike other MovieClip methods, the depth argument of an empty movie 
clip
     // can be any number. All numbers are converted to an int32_t, and are 
valid
     // depths even when outside the usual bounds.
-    ptr->addDisplayListObject(mc, toInt(fn.arg(1)));
+    ptr->addDisplayListObject(mc, toInt(fn.arg(1), getVM(fn)));
     return as_value(o);
 }
 
@@ -900,7 +900,7 @@ movieclip_loadMovie(const fn_call& fn)
     // TODO: if GET/POST should send variables of *this* movie,
     // no matter if the target will be replaced by another movie !!
     const MovieClip::VariablesMethod method =
-        static_cast<MovieClip::VariablesMethod>(toInt(val));
+        static_cast<MovieClip::VariablesMethod>(toInt(val, getVM(fn)));
 
     std::string data;
 
@@ -957,7 +957,7 @@ movieclip_loadVariables(const fn_call& fn)
     }
 
     const MovieClip::VariablesMethod method =
-        static_cast<MovieClip::VariablesMethod>(toInt(val));
+        static_cast<MovieClip::VariablesMethod>(toInt(val, getVM(fn)));
 
     movieclip->loadVariables(urlstr, method);
     log_debug("MovieClip.loadVariables(%s) - TESTING ", urlstr);
@@ -1067,7 +1067,7 @@ movieclip_getInstanceAtDepth(const fn_call& fn)
         return as_value();
     }
 
-    const int depth = toInt(fn.arg(0));
+    const int depth = toInt(fn.arg(0), getVM(fn));
 
     DisplayObject* ch = mc->getDisplayObjectAtDepth(depth);
  
@@ -1127,7 +1127,7 @@ movieclip_getURL(const fn_call& fn)
 
 
     MovieClip::VariablesMethod method =
-        static_cast<MovieClip::VariablesMethod>(toInt(val));
+        static_cast<MovieClip::VariablesMethod>(toInt(val, getVM(fn)));
 
     std::string vars;
 
@@ -1531,7 +1531,7 @@ movieclip_lineStyle(const fn_call& fn)
     switch (arguments) {
         default:
         case 8:
-            miterLimitFactor = clamp<int>(toInt(fn.arg(7)), 1, 255);
+            miterLimitFactor = clamp<int>(toInt(fn.arg(7), getVM(fn)), 1, 255);
         case 7:
         {
             std::string joinStyleStr = fn.arg(6).to_string();
@@ -1604,7 +1604,7 @@ movieclip_lineStyle(const fn_call& fn)
             // See pollock.swf for eventual regressions.
             // It sets color to a random number from
             // 0 to 160000000 (about 10 times more then the max).
-            boost::uint32_t rgbval = toInt(fn.arg(1));
+            boost::uint32_t rgbval = toInt(fn.arg(1), getVM(fn));
             r = boost::uint8_t((rgbval & 0xFF0000) >> 16);
             g = boost::uint8_t((rgbval & 0x00FF00) >> 8);
             b = boost::uint8_t((rgbval & 0x0000FF) );
@@ -1687,7 +1687,7 @@ movieclip_beginFill(const fn_call& fn)
     boost::uint8_t a = 255;
 
     if (fn.nargs > 1) {
-        a = 255 * clamp<int>(toInt(fn.arg(1)), 0, 100) / 100;
+        a = 255 * clamp<int>(toInt(fn.arg(1), getVM(fn)), 0, 100) / 100;
     }
 
     rgba color(r, g, b, a);
@@ -1811,7 +1811,7 @@ movieclip_beginGradientFill(const fn_call& fn)
         string_table::key key = st.find(boost::lexical_cast<std::string>(i));
 
         as_value colVal = getMember(*colors, key);
-        boost::uint32_t col = colVal.is_number() ? toInt(colVal) : 0;
+        boost::uint32_t col = colVal.is_number() ? toInt(colVal, getVM(fn)) : 
0;
 
         /// Alpha is the range 0..100.
         as_value alpVal = getMember(*alphas, key);
@@ -1833,7 +1833,8 @@ movieclip_beginGradientFill(const fn_call& fn)
             std::min<boost::uint32_t>(gradients[i - 1].ratio + step, 0xff);
 
         boost::uint8_t rat = ratVal.is_number() ? 
-            clamp<boost::uint32_t>(toInt(ratVal), minRatio, 0xff) : minRatio;
+            clamp<boost::uint32_t>(toInt(ratVal, getVM(fn)), minRatio, 0xff)
+            : minRatio;
 
         // The renderer may expect successively larger ratios; failure to
         // do this can lead to memory errors.
@@ -2059,7 +2060,7 @@ movieclip_attachBitmap(const fn_call& fn)
         return as_value();
     }
 
-    int depth = toInt(fn.arg(1));
+    int depth = toInt(fn.arg(1), getVM(fn));
 
     DisplayObject* bm = new Bitmap(getRoot(fn), 0, bd, ptr);
     ptr->attachCharacter(*bm, depth, 0);
diff --git a/libcore/asobj/Number_as.cpp b/libcore/asobj/Number_as.cpp
index d95edbb..1c0ec57 100644
--- a/libcore/asobj/Number_as.cpp
+++ b/libcore/asobj/Number_as.cpp
@@ -72,7 +72,7 @@ number_toString(const fn_call& fn)
 
     if ( fn.nargs ) 
     {
-        int userRadix = toInt(fn.arg(0));
+        int userRadix = toInt(fn.arg(0), getVM(fn));
         if ( userRadix >= 2 && userRadix <= 36 ) radix=userRadix;
         else
         {
diff --git a/libcore/asobj/Selection_as.cpp b/libcore/asobj/Selection_as.cpp
index 3d53414..e541ddd 100644
--- a/libcore/asobj/Selection_as.cpp
+++ b/libcore/asobj/Selection_as.cpp
@@ -245,8 +245,8 @@ selection_setSelection(const fn_call& fn)
         return as_value();
     }
 
-    int start = toInt(fn.arg(0));
-    int end = toInt(fn.arg(1));
+    int start = toInt(fn.arg(0), getVM(fn));
+    int end = toInt(fn.arg(1), getVM(fn));
 
     tf->setSelection(start, end);
 
diff --git a/libcore/asobj/SharedObject_as.cpp 
b/libcore/asobj/SharedObject_as.cpp
index 40257ad..2aa8e6d 100644
--- a/libcore/asobj/SharedObject_as.cpp
+++ b/libcore/asobj/SharedObject_as.cpp
@@ -758,7 +758,7 @@ sharedobject_flush(const fn_call& fn)
 
     int space = 0;
     if (fn.nargs) {
-        space = toInt(fn.arg(0));
+        space = toInt(fn.arg(0), getVM(fn));
     }
 
     /// If there is no data member, returns undefined.
diff --git a/libcore/asobj/String_as.cpp b/libcore/asobj/String_as.cpp
index 9ae1d61..e5f192c 100644
--- a/libcore/asobj/String_as.cpp
+++ b/libcore/asobj/String_as.cpp
@@ -178,13 +178,13 @@ string_slice(const fn_call& fn)
 
     if (!checkArgs(fn, 1, 2, "String.slice()")) return as_value();
 
-    size_t start = validIndex(wstr, toInt(fn.arg(0)));
+    size_t start = validIndex(wstr, toInt(fn.arg(0), getVM(fn)));
 
     size_t end = wstr.length();
 
     if (fn.nargs >= 2)
     {
-        end = validIndex(wstr, toInt(fn.arg(1)));
+        end = validIndex(wstr, toInt(fn.arg(1), getVM(fn)));
 
     } 
 
@@ -260,7 +260,7 @@ string_split(const fn_call& fn)
         // SWF5
         if (fn.nargs > 1 && !fn.arg(1).is_undefined())
         {
-            int limit = toInt(fn.arg(1));
+            int limit = toInt(fn.arg(1), getVM(fn));
             if (limit < 1)
             {
                 // Return empty array.
@@ -293,7 +293,7 @@ string_split(const fn_call& fn)
         // the delimiter is defined.
         if (fn.nargs > 1 && !fn.arg(1).is_undefined())
         {
-            int limit = toInt(fn.arg(1));
+            int limit = toInt(fn.arg(1), getVM(fn));
             if (limit < 1) {
                 // Return empty array if 
                 return as_value(array);
@@ -351,7 +351,7 @@ string_lastIndexOf(const fn_call& fn)
     int start = str.size();
 
     if (fn.nargs >= 2) {
-        start = toInt(fn.arg(1));
+        start = toInt(fn.arg(1), getVM(fn));
     }
     
     if (start < 0) {
@@ -384,13 +384,13 @@ string_substr(const fn_call& fn)
 
     if (!checkArgs(fn, 1, 2, "String.substr()")) return as_value(str);
     
-    int start = validIndex(wstr, toInt(fn.arg(0)));
+    int start = validIndex(wstr, toInt(fn.arg(0), getVM(fn)));
 
     int num = wstr.length();
 
     if (fn.nargs >= 2 && !fn.arg(1).is_undefined())
     {
-        num = toInt(fn.arg(1));
+        num = toInt(fn.arg(1), getVM(fn));
         if ( num < 0 )
         {
             if ( -num <= start ) num = 0;
@@ -424,7 +424,7 @@ string_substring(const fn_call& fn)
 
     const as_value& s = fn.arg(0);
 
-    int start = toInt(s);
+    int start = toInt(s, getVM(fn));
     int end = wstr.size();
 
     if (s.is_undefined() || start < 0) {
@@ -436,7 +436,7 @@ string_substring(const fn_call& fn)
     }
 
     if (fn.nargs >= 2 && !fn.arg(1).is_undefined()) {
-        int num = toInt(fn.arg(1));
+        int num = toInt(fn.arg(1), getVM(fn));
 
         if (num < 0) {
             num = 0;
@@ -486,21 +486,19 @@ string_indexOf(const fn_call& fn)
     if (fn.nargs >= 2)
     {
         const as_value& saval = fn.arg(1); // start arg val
-        int start_arg = toInt(saval);
-        if ( start_arg > 0 ) start = (size_t) start_arg;
-    else
-    {
-        IF_VERBOSE_ASCODING_ERRORS(
-        if ( start_arg < 0 )
-        {
-            log_aserror("String.indexOf(%s, %s): second argument casts to 
invalid offset (%d)",
-                tfarg, saval, start_arg);
+        int start_arg = toInt(saval, getVM(fn));
+        if (start_arg > 0) start = (size_t) start_arg;
+        else {
+            IF_VERBOSE_ASCODING_ERRORS(
+                if (start_arg < 0) {
+                    log_aserror("String.indexOf(%s, %s): second argument casts 
"
+                        "to invalid offset (%d)", tfarg, saval, start_arg);
+                }
+            );
         }
-        );
-    }
     }
 
-    size_t pos = wstr.find(toFind, start);
+    const size_t pos = wstr.find(toFind, start);
 
     if (pos == std::wstring::npos) {
         return as_value(-1);
@@ -524,11 +522,11 @@ string_fromCharCode(const fn_call& fn)
         for (unsigned int i = 0; i < fn.nargs; i++)
         {
             // Maximum 65535, as with all DisplayObject codes.
-            boost::uint16_t c = static_cast<boost::uint16_t>(toInt(fn.arg(i)));
+            const boost::uint16_t c = 
+                static_cast<boost::uint16_t>(toInt(fn.arg(i), getVM(fn)));
             
             // If more than 255, push 'overflow' byte.
-            if (c > 255)
-            {
+            if (c > 255) {
                 str.push_back(static_cast<unsigned char>(c >> 8));
             }
 
@@ -544,7 +542,8 @@ string_fromCharCode(const fn_call& fn)
 
     for (unsigned int i = 0; i < fn.nargs; i++)
     {
-        boost::uint16_t c = static_cast<boost::uint16_t>(toInt(fn.arg(i)));
+        const boost::uint16_t c = 
+            static_cast<boost::uint16_t>(toInt(fn.arg(i), getVM(fn)));
         if (c == 0) break;
         wstr.push_back(c);
     }
@@ -600,7 +599,7 @@ string_charAt(const fn_call& fn)
     if (!checkArgs(fn, 1, 1, "String.charAt()")) return as_value("");
 
     // to_int() makes this safe from overflows.
-    const size_t index = static_cast<size_t>(toInt(fn.arg(0)));
+    const size_t index = static_cast<size_t>(toInt(fn.arg(0), getVM(fn)));
 
     size_t currentIndex = 0;
 
diff --git a/libcore/asobj/TextField_as.cpp b/libcore/asobj/TextField_as.cpp
index 1e11262..4e1b685 100644
--- a/libcore/asobj/TextField_as.cpp
+++ b/libcore/asobj/TextField_as.cpp
@@ -226,11 +226,11 @@ textfield_createTextField(const fn_call& fn)
     }
 
     const std::string& name = fn.arg(0).to_string();
-    const int depth = toInt(fn.arg(1));
-    const int x = toInt(fn.arg(2));
-    const int y = toInt(fn.arg(3));
+    const int depth = toInt(fn.arg(1), getVM(fn));
+    const int x = toInt(fn.arg(2), getVM(fn));
+    const int y = toInt(fn.arg(3), getVM(fn));
     
-    int width = toInt(fn.arg(4));
+    int width = toInt(fn.arg(4), getVM(fn));
     if (width < 0) {
         IF_VERBOSE_ASCODING_ERRORS(
         log_aserror(_("createTextField: negative width (%d)"
@@ -239,7 +239,7 @@ textfield_createTextField(const fn_call& fn)
         width = -width;
     }
 
-    int height = toInt(fn.arg(5));
+    int height = toInt(fn.arg(5), getVM(fn));
     if ( height < 0 )
     {
         IF_VERBOSE_ASCODING_ERRORS(
@@ -317,7 +317,7 @@ textfield_backgroundColor(const fn_call& fn)
     }
     else {
         rgba newColor;
-        newColor.parseRGB(static_cast<boost::uint32_t>(toInt(fn.arg(0))));
+        newColor.parseRGB(static_cast<boost::uint32_t>(toInt(fn.arg(0), 
getVM(fn))));
         ptr->setBackgroundColor(newColor);
     }
 
@@ -845,7 +845,7 @@ textfield_maxChars(const fn_call& fn)
         return as_value(maxChars);
     }
     // Setter
-    text->maxChars(toInt(fn.arg(0)));
+    text->maxChars(toInt(fn.arg(0), getVM(fn)));
     return as_value();
 }
 
@@ -989,7 +989,7 @@ textfield_replaceText(const fn_call& fn)
         return as_value();
     }
 
-    int userEnd = toInt(fn.arg(1));
+    int userEnd = toInt(fn.arg(1), getVM(fn));
     if ( userEnd < 0 )
     {
         IF_VERBOSE_ASCODING_ERRORS(
@@ -1000,7 +1000,7 @@ textfield_replaceText(const fn_call& fn)
         return as_value();
     }
 
-    wstring::size_type start = toInt(fn.arg(0));
+    wstring::size_type start = toInt(fn.arg(0), getVM(fn));
     wstring::size_type end = userEnd;
 
     int version = getSWFVersion(fn);
diff --git a/libcore/asobj/TextFormat_as.cpp b/libcore/asobj/TextFormat_as.cpp
index e18fa16..cc99c5f 100644
--- a/libcore/asobj/TextFormat_as.cpp
+++ b/libcore/asobj/TextFormat_as.cpp
@@ -63,7 +63,7 @@ PositiveTwips : SetBase
 {
     PositiveTwips(const fn_call& fn) : SetBase(fn) {}
     int operator()(const as_value& val) const {
-        return pixelsToTwips(std::max<int>(toInt(val), 0));
+        return pixelsToTwips(std::max<int>(toInt(val, getVM(fn())), 0));
     }
 };
 
@@ -407,13 +407,13 @@ textformat_new(const fn_call& fn)
            default:
                log_error(_("Too many args (%d) passed to TextFormat"), args);
            case 13:
-               tf->leadingSet(pixelsToTwips(toInt(fn.arg(12))));
+               tf->leadingSet(pixelsToTwips(toInt(fn.arg(12), getVM(fn))));
            case 12:
-               tf->indentSet(pixelsToTwips(toInt(fn.arg(11))));
+               tf->indentSet(pixelsToTwips(toInt(fn.arg(11), getVM(fn))));
            case 11:
-               tf->rightMarginSet(pixelsToTwips(toInt(fn.arg(10))));
+               tf->rightMarginSet(pixelsToTwips(toInt(fn.arg(10), getVM(fn))));
            case 10:
-               tf->leftMarginSet(pixelsToTwips(toInt(fn.arg(9))));
+               tf->leftMarginSet(pixelsToTwips(toInt(fn.arg(9), getVM(fn))));
            case 9:
                tf->alignSet(fn.arg(8).to_string());
            case 8:
@@ -429,11 +429,11 @@ textformat_new(const fn_call& fn)
            case 3:
            {
                rgba col;
-               col.parseRGB(toInt(fn.arg(2)));
+               col.parseRGB(toInt(fn.arg(2), getVM(fn)));
                tf->colorSet(col);
            }
            case 2:
-               tf->sizeSet(pixelsToTwips(toInt(fn.arg(1))));
+               tf->sizeSet(pixelsToTwips(toInt(fn.arg(1), getVM(fn))));
            case 1:
                tf->fontSet(fn.arg(0).to_string());
                break;
@@ -514,7 +514,7 @@ textformat_color(const fn_call& fn)
        }
        else {
                rgba newcolor;
-               newcolor.parseRGB(toInt(fn.arg(0)));
+               newcolor.parseRGB(toInt(fn.arg(0), getVM(fn)));
                relay->colorSet(newcolor);
        }
 
diff --git a/libcore/asobj/TextSnapshot_as.cpp 
b/libcore/asobj/TextSnapshot_as.cpp
index 1293132..58d4237 100644
--- a/libcore/asobj/TextSnapshot_as.cpp
+++ b/libcore/asobj/TextSnapshot_as.cpp
@@ -499,8 +499,10 @@ textsnapshot_getTextRunInfo(const fn_call& fn)
         return as_value();
     }
 
-    size_t start = std::max<boost::int32_t>(0, toInt(fn.arg(0)));
-    size_t end = std::max<boost::int32_t>(start + 1, toInt(fn.arg(1)));
+    const size_t start = std::max<boost::int32_t>(0,
+            toInt(fn.arg(0), getVM(fn)));
+    const size_t end = std::max<boost::int32_t>(start + 1,
+            toInt(fn.arg(1), getVM(fn)));
 
     Global_as& gl = getGlobal(fn);
     as_object* ri = gl.createArray();
@@ -524,7 +526,7 @@ textsnapshot_findText(const fn_call& fn)
         return as_value();
     }
 
-    boost::int32_t start = toInt(fn.arg(0));
+    boost::int32_t start = toInt(fn.arg(0), getVM(fn));
     const std::string& text = fn.arg(1).to_string();
 
     /// Yes, the pp is case-insensitive by default. We don't write
@@ -563,8 +565,10 @@ textsnapshot_getSelected(const fn_call& fn)
         return as_value();
     }
 
-    size_t start = std::max<boost::int32_t>(0, toInt(fn.arg(0)));
-    size_t end = std::max<boost::int32_t>(start + 1, toInt(fn.arg(1)));
+    const size_t start = std::max<boost::int32_t>(0,
+            toInt(fn.arg(0), getVM(fn)));
+    const size_t end = std::max<boost::int32_t>(start + 1,
+            toInt(fn.arg(1), getVM(fn)));
 
     return as_value(ts->getSelected(start, end));
 }
@@ -602,8 +606,8 @@ textsnapshot_getText(const fn_call& fn)
         return as_value();
     }
 
-    boost::int32_t start = toInt(fn.arg(0));
-    boost::int32_t end = toInt(fn.arg(1));
+    const boost::int32_t start = toInt(fn.arg(0), getVM(fn));
+    const boost::int32_t end = toInt(fn.arg(1), getVM(fn));
 
     const bool newline = (fn.nargs > 2) ? toBool(fn.arg(2), getVM(fn)) : false;
 
@@ -647,8 +651,10 @@ textsnapshot_setSelected(const fn_call& fn)
         return as_value();
     }
 
-    const size_t start = std::max<boost::int32_t>(0, toInt(fn.arg(0)));
-    const size_t end = std::max<boost::int32_t>(start, toInt(fn.arg(1)));
+    const size_t start = std::max<boost::int32_t>(0,
+            toInt(fn.arg(0), getVM(fn)));
+    const size_t end = std::max<boost::int32_t>(start,
+            toInt(fn.arg(1), getVM(fn)));
 
     const bool selected = (fn.nargs > 2) ? toBool(fn.arg(2), getVM(fn)) : true;
 
diff --git a/libcore/asobj/XMLNode_as.cpp b/libcore/asobj/XMLNode_as.cpp
index 2c68b4f..2ef8c8f 100644
--- a/libcore/asobj/XMLNode_as.cpp
+++ b/libcore/asobj/XMLNode_as.cpp
@@ -565,7 +565,7 @@ xmlnode_new(const fn_call& fn)
     }
 
     std::auto_ptr<XMLNode_as> xml(new XMLNode_as(getGlobal(fn)));
-    xml->nodeTypeSet(XMLNode_as::NodeType(toInt(fn.arg(0))));
+    xml->nodeTypeSet(XMLNode_as::NodeType(toInt(fn.arg(0), getVM(fn))));
 
     if (fn.nargs > 1) {
         const std::string& str = fn.arg(1).to_string();
diff --git a/libcore/asobj/flash/display/BitmapData_as.cpp 
b/libcore/asobj/flash/display/BitmapData_as.cpp
index 18842f5..8585e89 100644
--- a/libcore/asobj/flash/display/BitmapData_as.cpp
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp
@@ -505,9 +505,10 @@ bitmapdata_fillRect(const fn_call& fn)
     obj->get_member(NSV::PROP_WIDTH, &w);
     obj->get_member(NSV::PROP_HEIGHT, &h);    
 
-    const boost::uint32_t color = toInt(fn.arg(1));
+    const boost::uint32_t color = toInt(fn.arg(1), getVM(fn));
        
-    ptr->fillRect(toInt(x), toInt(y), toInt(w), toInt(h), color);
+    ptr->fillRect(toInt(x, getVM(fn)), toInt(y, getVM(fn)),
+            toInt(w, getVM(fn)), toInt(h, getVM(fn)), color);
     
        return as_value();
 }
@@ -530,14 +531,14 @@ bitmapdata_floodFill(const fn_call& fn)
         return as_value();
     }
     
-    const int x = toInt(fn.arg(0));
-    const int y = toInt(fn.arg(1));
+    const int x = toInt(fn.arg(0), getVM(fn));
+    const int y = toInt(fn.arg(1), getVM(fn));
 
     if (x < 0 || y < 0) {
         return as_value();
     }
 
-    const boost::uint32_t fill = toInt(fn.arg(2));
+    const boost::uint32_t fill = toInt(fn.arg(2), getVM(fn));
     const boost::uint32_t old = *pixelAt(*ptr, x, y);
 
     // This checks whether the colours are the same.
@@ -580,8 +581,8 @@ bitmapdata_getPixel(const fn_call& fn)
         return as_value();
     }
     
-    const int x = toInt(fn.arg(0));
-    const int y = toInt(fn.arg(1));
+    const int x = toInt(fn.arg(0), getVM(fn));
+    const int y = toInt(fn.arg(1), getVM(fn));
     
     // Will return 0 if the pixel is outside the image or the image has
     // been disposed.
@@ -605,8 +606,8 @@ bitmapdata_getPixel32(const fn_call& fn)
     }
     
     // TODO: what happens when the pixel is outside the image?
-    const int x = toInt(fn.arg(0));
-    const int y = toInt(fn.arg(1));
+    const int x = toInt(fn.arg(0), getVM(fn));
+    const int y = toInt(fn.arg(1), getVM(fn));
     
     return static_cast<boost::int32_t>(ptr->getPixel(x, y));
 }
@@ -692,7 +693,7 @@ bitmapdata_setPixel(const fn_call& fn)
     }
 
     // Ignore any transparency here.
-    const boost::uint32_t color = toInt(fn.arg(2));
+    const boost::uint32_t color = toInt(fn.arg(2), getVM(fn));
 
     ptr->setPixel(x, y, color);
 
@@ -716,7 +717,7 @@ bitmapdata_setPixel32(const fn_call& fn)
     }
 
     // TODO: multiply.
-    const boost::uint32_t color = toInt(fn.arg(2));
+    const boost::uint32_t color = toInt(fn.arg(2), getVM(fn));
 
     ptr->setPixel32(x, y, color);
 
@@ -879,10 +880,10 @@ bitmapdata_ctor(const fn_call& fn)
         throw ActionTypeError();
        }
 
-    size_t width = toInt(fn.arg(0));
-    size_t height = toInt(fn.arg(1));
+    size_t width = toInt(fn.arg(0), getVM(fn));
+    size_t height = toInt(fn.arg(1), getVM(fn));
     const bool transparent = fn.nargs > 2 ? toBool(fn.arg(2), getVM(fn)) : 
true;
-    boost::uint32_t fillColor = fn.nargs > 3 ? toInt(fn.arg(3)) : 0xffffffff;
+    boost::uint32_t fillColor = fn.nargs > 3 ? toInt(fn.arg(3), getVM(fn)) : 
0xffffffff;
     
     if (width > 2880 || height > 2880 || width < 1 || height < 1) {
         IF_VERBOSE_ASCODING_ERRORS(
diff --git a/libcore/asobj/flash/geom/ColorTransform_as.cpp 
b/libcore/asobj/flash/geom/ColorTransform_as.cpp
index 2333fa0..d71872f 100644
--- a/libcore/asobj/flash/geom/ColorTransform_as.cpp
+++ b/libcore/asobj/flash/geom/ColorTransform_as.cpp
@@ -339,7 +339,7 @@ colortransform_rgb(const fn_call& fn)
 
     // Setter
 
-    boost::uint32_t rgb = toInt(fn.arg(0));
+    boost::uint32_t rgb = toInt(fn.arg(0), getVM(fn));
     relay->setRedOffset((rgb & 0xFF0000) >> 16);
     relay->setGreenOffset((rgb & 0x00FF00) >> 8);
     relay->setBlueOffset(rgb & 0x0000FF);
diff --git a/libcore/vm/ASHandlers.cpp b/libcore/vm/ASHandlers.cpp
index f7f7201..5e76efa 100644
--- a/libcore/vm/ASHandlers.cpp
+++ b/libcore/vm/ASHandlers.cpp
@@ -894,8 +894,8 @@ ActionSubString(ActionExec& thread)
     const as_value& strval = env.top(2);
 
     // Undefined values should resolve to 0.
-    int size = toInt(env.top(0));
-    int start = toInt(env.top(1));
+    int size = toInt(env.top(0), getVM(env));
+    int start = toInt(env.top(1), getVM(env));
 
     const int version = env.get_version();
     const std::wstring wstr = utf8::decodeCanonicalString(
@@ -971,7 +971,7 @@ void
 ActionInt(ActionExec& thread)
 {
     as_environment& env = thread.env;
-    env.top(0).set_double(toInt(env.top(0)));
+    env.top(0).set_double(toInt(env.top(0), getVM(env)));
 }
 
 void
@@ -1469,7 +1469,7 @@ ActionFscommand2(ActionExec& thread)
 
     unsigned int off=0;
     
-    const unsigned int nargs = toInt(env.top(off++));
+    const unsigned int nargs = toInt(env.top(off++), getVM(env));
 
     std::string cmd = env.top(off++).to_string();
 
@@ -1502,7 +1502,7 @@ ActionRandom(ActionExec& thread)
     
     as_environment& env = thread.env;
 
-    int max = toInt(env.top(0));
+    int max = toInt(env.top(0), getVM(env));
 
     if (max < 1) max = 1;
 
@@ -1573,7 +1573,8 @@ ActionChr(ActionExec& thread)
     as_environment& env = thread.env;
     
     // Only handles values up to 65535
-    boost::uint16_t c = static_cast<boost::uint16_t>(toInt(env.top(0)));
+    const boost::uint16_t c =
+        static_cast<boost::uint16_t>(toInt(env.top(0), getVM(env)));
 
     // If the argument to chr() is '0', we return
     // nothing, not NULL
@@ -1624,8 +1625,8 @@ ActionMbSubString(ActionExec& thread)
     const as_value& arg1 = env.top(1);
 
     // Undefined values should resolve to 0.
-    int size = toInt(env.top(0));
-    int start = toInt(env.top(1));
+    int size = toInt(env.top(0), getVM(env));
+    int start = toInt(env.top(1), getVM(env));
 
     as_value& string_val = env.top(2);
 
@@ -1736,7 +1737,7 @@ ActionMbChr(ActionExec& thread)
     }
 
     // Cut to uint16, as characters above 65535 'wrap around'
-    const boost::uint16_t i = static_cast<boost::uint16_t> (toInt(env.top(0)));
+    const boost::uint16_t i = static_cast<boost::uint16_t> (toInt(env.top(0), 
getVM(env)));
     
     std::string out = utf8::encodeUnicodeCharacter(i);
     
@@ -2477,7 +2478,7 @@ ActionInitArray(ActionExec& thread)
     
     as_environment& env = thread.env;
 
-    const int array_size = toInt(env.pop());
+    const int array_size = toInt(env.pop(), getVM(env));
     assert(array_size >= 0); // TODO: trigger this !!
     
     Global_as& gl = getGlobal(env);
@@ -2510,7 +2511,7 @@ ActionInitObject(ActionExec& thread)
     //     [003]   Integer: 1
     //    SWFACTION_INITOBJECT
 
-    const int nmembers = toInt(env.pop());
+    const int nmembers = toInt(env.pop(), getVM(env));
 
     // TODO: see if this could call the ASnative function(101, 9).
     Global_as& gl = getGlobal(env);
@@ -3113,8 +3114,8 @@ ActionBitwiseAnd(ActionExec& thread)
 {
     as_environment& env = thread.env;
 
-    const int operand1 = toInt(env.top(1));
-    const int operand2 = toInt(env.top(0));
+    const int operand1 = toInt(env.top(1), getVM(env));
+    const int operand2 = toInt(env.top(0), getVM(env));
 
     env.top(1) = operand1 & operand2;
     env.drop(1);
@@ -3125,8 +3126,8 @@ ActionBitwiseOr(ActionExec& thread)
 {
     as_environment& env = thread.env;
 
-    const int operand1 = toInt(env.top(1));
-    const int operand2 = toInt(env.top(0));
+    const int operand1 = toInt(env.top(1), getVM(env));
+    const int operand2 = toInt(env.top(0), getVM(env));
 
     env.top(1) = operand1|operand2;
     env.drop(1);
@@ -3137,8 +3138,8 @@ ActionBitwiseXor(ActionExec& thread)
 {
     as_environment& env = thread.env;
 
-    const int operand1 = toInt(env.top(1));
-    const int operand2 = toInt(env.top(0));
+    const int operand1 = toInt(env.top(1), getVM(env));
+    const int operand2 = toInt(env.top(0), getVM(env));
 
     env.top(1) = operand1^operand2;
     env.drop(1);
@@ -3153,10 +3154,10 @@ ActionShiftLeft(ActionExec& thread)
     /// A left shift of more than or equal to the size in
     /// bits of the left operand, or a negative shift, results
     /// in undefined behaviour in C++.
-    boost::int32_t amount = toInt(env.top(0)) % 32;
+    boost::int32_t amount = toInt(env.top(0), getVM(env)) % 32;
     if (amount < 0) amount += 32;
     
-    boost::int32_t value = toInt(env.top(1));
+    boost::int32_t value = toInt(env.top(1), getVM(env));
 
     value = value << amount;
 
@@ -3170,8 +3171,8 @@ ActionShiftRight(ActionExec& thread)
 
     as_environment& env = thread.env;
 
-    boost::uint32_t amount = toInt(env.top(0));
-    boost::int32_t value = toInt(env.top(1));
+    boost::uint32_t amount = toInt(env.top(0), getVM(env));
+    boost::int32_t value = toInt(env.top(1), getVM(env));
 
     value = value >> amount;
 
@@ -3184,8 +3185,8 @@ ActionShiftRight2(ActionExec& thread)
 {
     as_environment& env = thread.env;
 
-    boost::uint32_t amount = toInt(env.top(0)); 
-    boost::int32_t value = toInt(env.top(1));
+    boost::uint32_t amount = toInt(env.top(0), getVM(env)); 
+    boost::int32_t value = toInt(env.top(1), getVM(env));
 
     value = boost::uint32_t(value) >> amount;
 
diff --git a/libcore/vm/VM.cpp b/libcore/vm/VM.cpp
index 80836fd..7f906b6 100644
--- a/libcore/vm/VM.cpp
+++ b/libcore/vm/VM.cpp
@@ -43,7 +43,7 @@
 #include "rc.h" 
 #include "namedStrings.h"
 #include "VirtualClock.h" // for getTime()
-
+#include "GnashNumeric.h"
 
 namespace {
 gnash::RcInitFile& rcfile = gnash::RcInitFile::getDefaultInstance();
@@ -521,7 +521,7 @@ toNumber(const as_value& v, const VM& vm)
 boost::int32_t
 toInt(const as_value& v, const VM& vm)
 {
-    const double d = val.to_number(vm.getSWFVersion());
+    const double d = v.to_number(vm.getSWFVersion());
 
     if (!isFinite(d)) return 0;
 
diff --git a/libcore/vm/VM.h b/libcore/vm/VM.h
index b0aec52..d5c5dfe 100644
--- a/libcore/vm/VM.h
+++ b/libcore/vm/VM.h
@@ -431,9 +431,13 @@ bool toBool(const as_value& v, const VM& vm);
 /// Convert an as_value to number type
 double toNumber(const as_value& v, const VM& vm);
 
-/// Convert an as_value to a 32-bit signed integer
+/// AS2-compatible conversion to 32bit integer
 //
-/// Large numbers are truncated.
+/// This truncates large numbers to fit in the 32-bit space. It is not a 
+/// proper function of as_value because it is simply a further operation on
+/// the stored number type.
+//
+/// This function calls to_number(), so performs a conversion if necessary.
 boost::int32_t toInt(const as_value& val, const VM& vm);
 
 /// Force type to number.
diff --git a/testsuite/libcore.all/AsValueTest.cpp 
b/testsuite/libcore.all/AsValueTest.cpp
index e784521..e1e5ed1 100644
--- a/testsuite/libcore.all/AsValueTest.cpp
+++ b/testsuite/libcore.all/AsValueTest.cpp
@@ -194,139 +194,6 @@ test_conversion()
     
 }
 
-#if 0
-void
-test_el()
-{
-//    bool notest = false;
-    
-    Element el1;
-    el1.makeNumber(1.234);
-    as_value as1(el1);
-    if (as1.to_number() == el1.to_number()) {
-        runtest.pass("as_value(Element &number)");
-    } else {
-        runtest.fail("as_value(Element &number)");
-    }
-
-    Element el2;
-    el2.makeString("Hello World");
-    as_value as2(el2);
-    if (as2.to_string() == el2.to_string()) {
-        runtest.pass("as_value(Element &string)");
-    } else {
-        runtest.fail("as_value(Element &string)");
-    }
-    
-    Element el3;
-    el3.makeBoolean(true);
-    as_value as3(el3);    
-    if ((as3.is_bool()) && (as3.to_bool() == true)) {
-        runtest.pass("as_value(Element &bool)");
-    } else {
-        runtest.fail("as_value(Element &bool)");
-    }
-
-    Element el4;
-    el4.makeUndefined();
-    as_value as4(el4);
-    if (as4.is_undefined()) {
-        runtest.pass("as_value(Element &undefined)");
-    } else {
-        runtest.fail("as_value(Element &undefined)");
-    }
-    
-    // As for misc-ming.all/SharedObjectTest, MOVIECLIP values are serialized
-    // as undefined values.
-    //
-    //Element el5;
-    //el5.makeMovieClip();
-    //as_value as5(el5);
-    //if (as5.is_sprite()) {
-    //   runtest.pass("as_value(Element &movieclip)");
-    //} else {
-    //    runtest.fail("as_value(Element &movieclip)");
-    //}
-
-    // There is no equivalent AMF element type to the as_value AS_FUNCTION type
-}
-
-void
-test_obj(const as_object* o)
-{
-    // Create an object element with some properties
-    bool notest = false;
-    Element top;
-    top.makeObject("toplevel");
-
-    boost::shared_ptr<amf::Element> foo(new Element);
-    foo->makeString("foo", "bar");
-    top.addProperty(foo);
-
-    boost::shared_ptr<amf::Element> bar(new Element);
-    bar->makeNumber("bar", 1.234);
-    top.addProperty(bar);
-
-    if (top.propertySize() != 2) {
-        notest = true;
-    }
-    VM& vm = VM::get();
-    string_table& st = vm.getStringTable();
-
-    as_value as1(top);
-    
-    if (as1.is_object()) {
-        runtest.pass("as_value(Element object)");
-    } else {
-        notest = true;
-        runtest.fail("as_value(Element object)");
-    }
-
-    as_value fooas, baras;
-    boost::intrusive_ptr<as_object> ao1 = as1.to_object(getGlobal(*o));
-
-    if (ao1 == 0) {
-        notest= true;
-    }
-        
-    if (notest) {
-        runtest.unresolved("as_value(Element &prop1)");
-    } else {
-        if (ao1.get() == 0) {
-            runtest.unresolved("as_value(Element &prop1)");
-        } else {
-            ao1.get()->get_member(st.find("foo"), &fooas);
-            ao1.get()->get_member(st.find("bar"), &baras);
-            if ((fooas.is_string()) && (fooas.to_string() == 
foo->to_string())) {
-                runtest.pass("as_value(Element prop1)");
-            } else {
-                runtest.fail("as_value(Element prop1)");
-            }
-            if ((baras.is_number()) && (baras.to_number() == 
bar->to_number())) {
-                runtest.pass("as_value(Element prop2)");
-            } else {
-                runtest.fail("as_value(Element prop2)");
-            }
-        }
-    }
-
-    boost::shared_ptr<Element> el1 = as1.to_element();
-    boost::shared_ptr<amf::Element> fooel = el1->getProperty(0);
-    boost::shared_ptr<amf::Element> barel = el1->getProperty(1);
-    if ((el1.get()->getType() == Element::OBJECT_AMF0)
-        && (fooel->getType() == Element::STRING_AMF0)
-        && (strcmp(fooel->getName(), "foo") == 0)
-        && (strcmp(fooel->to_string(), "bar") == 0)
-        && (barel->getType() == Element::NUMBER_AMF0)
-        && (strcmp(barel->getName(), "bar") == 0)
-        && (barel->to_number() == 1.234)
-        ) {
-        runtest.pass("as_value::to_element()");
-    } else {
-        runtest.fail("as_value::to_element()");
-    }
-}
-#endif
 
 void
 test_isnan()
diff --git a/testsuite/misc-ming.all/DefineTextTest-Runner.cpp 
b/testsuite/misc-ming.all/DefineTextTest-Runner.cpp
index 9572bdc..db9eb27 100644
--- a/testsuite/misc-ming.all/DefineTextTest-Runner.cpp
+++ b/testsuite/misc-ming.all/DefineTextTest-Runner.cpp
@@ -117,7 +117,7 @@ main(int /*argc*/, char** /*argv*/)
        bool endOfTestFound = getObject(root)->get_member(st.find("endoftest"), 
&eot);
        xcheck(endOfTestFound);
        xcheck(eot.is_bool());
-       xcheck(eot.to_bool());
+       xcheck(eot.to_bool(8));
 
        // TODO: use check_pixel for checking bacground colors
 }
diff --git a/testsuite/misc-ming.all/DragDropTestRunner.cpp 
b/testsuite/misc-ming.all/DragDropTestRunner.cpp
index 3ce42a2..5728507 100644
--- a/testsuite/misc-ming.all/DragDropTestRunner.cpp
+++ b/testsuite/misc-ming.all/DragDropTestRunner.cpp
@@ -175,7 +175,7 @@ main(int /*argc*/, char** /*argv*/)
        if ( endOfTestFound )
        {
                cerr << eot << endl;
-               check_equals(eot.to_bool(), true);
+               check_equals(eot.to_bool(8), true);
        }
        else
        {
diff --git a/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp 
b/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
index 6908256..0025ab2 100644
--- a/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
+++ b/testsuite/misc-ming.all/PrototypeEventListenersTestRunner.cpp
@@ -78,7 +78,7 @@ main(int /*argc*/, char** /*argv*/)
        if ( endOfTestFound )
        {
                cerr << eot << endl;
-               check_equals(eot.to_bool(), true);
+               check_equals(eot.to_bool(8), true);
        }
        else
        {
diff --git a/testsuite/misc-ming.all/loadMovieTestRunner.cpp 
b/testsuite/misc-ming.all/loadMovieTestRunner.cpp
index f4cb2f3..63413fe 100644
--- a/testsuite/misc-ming.all/loadMovieTestRunner.cpp
+++ b/testsuite/misc-ming.all/loadMovieTestRunner.cpp
@@ -198,7 +198,7 @@ main(int /*argc*/, char** /*argv*/)
        check(endOfTestFound);
        if ( endOfTestFound )
        {
-               check_equals(eot.to_bool(), true);
+               check_equals(eot.to_bool(8), true);
        }
 
 }
diff --git a/testsuite/misc-swfc.all/button_test1runner.cpp 
b/testsuite/misc-swfc.all/button_test1runner.cpp
index 88fdca7..eb39d2b 100644
--- a/testsuite/misc-swfc.all/button_test1runner.cpp
+++ b/testsuite/misc-swfc.all/button_test1runner.cpp
@@ -161,6 +161,6 @@ main(int /*argc*/, char** /*argv*/)
     getObject(root)->get_member(st.find("testcompleted"), &eot);
         
        //cerr << "EOT is " << eot.to_debug_string() << endl;
-       check(eot.to_bool());
+       check(eot.to_bool(8));
 }
 

http://git.savannah.gnu.org/cgit//commit/?id=d8ac7a62591c827a0a6a37d18580568a0a01ea1f


commit d8ac7a62591c827a0a6a37d18580568a0a01ea1f
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 08:41:45 2010 +0200

    Add toInt function with VM arg.

diff --git a/libcore/vm/VM.cpp b/libcore/vm/VM.cpp
index a963a25..80836fd 100644
--- a/libcore/vm/VM.cpp
+++ b/libcore/vm/VM.cpp
@@ -27,7 +27,8 @@
 #include <iostream>
 #include <memory>
 #include <boost/random.hpp> // for random generator
-#include <cstdlib> // std::getenv
+#include <cstdlib> 
+#include <cmath>
 #ifdef HAVE_SYS_UTSNAME_H
 # include <sys/utsname.h> // For system information
 #endif
@@ -517,6 +518,20 @@ toNumber(const as_value& v, const VM& vm)
     return v.to_number(vm.getSWFVersion());
 }
 
+boost::int32_t
+toInt(const as_value& v, const VM& vm)
+{
+    const double d = val.to_number(vm.getSWFVersion());
+
+    if (!isFinite(d)) return 0;
+
+    if (d < 0) {   
+        return - static_cast<boost::uint32_t>(std::fmod(-d, 4294967296.0));
+    }
+    
+    return static_cast<boost::uint32_t>(std::fmod(d, 4294967296.0));
+}
+
 /// Force type to number.
 as_value&
 convertToNumber(as_value& v, const VM& vm)
diff --git a/libcore/vm/VM.h b/libcore/vm/VM.h
index bd3266d..b0aec52 100644
--- a/libcore/vm/VM.h
+++ b/libcore/vm/VM.h
@@ -431,6 +431,11 @@ bool toBool(const as_value& v, const VM& vm);
 /// Convert an as_value to number type
 double toNumber(const as_value& v, const VM& vm);
 
+/// Convert an as_value to a 32-bit signed integer
+//
+/// Large numbers are truncated.
+boost::int32_t toInt(const as_value& val, const VM& vm);
+
 /// Force type to number.
 as_value& convertToNumber(as_value& v, const VM& vm);
 

http://git.savannah.gnu.org/cgit//commit/?id=7af4e6cc88eb803845ac826c72f53f0b50388f48


commit 7af4e6cc88eb803845ac826c72f53f0b50388f48
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 08:37:13 2010 +0200

    Move functions to VM

diff --git a/libcore/as_value.cpp b/libcore/as_value.cpp
index eb48969..92bf8bb 100644
--- a/libcore/as_value.cpp
+++ b/libcore/as_value.cpp
@@ -935,38 +935,6 @@ doubleToString(double val, int radix)
     return str;
 }
 
-/// Force type to number.
-as_value&
-convertToNumber(as_value& v, const VM& vm)
-{
-    v.set_double(v.to_number(vm.getSWFVersion()));
-    return v;
-}
-
-/// Force type to string.
-as_value&
-convertToString(as_value& v, const VM& vm)
-{
-    v.set_string(v.to_string(vm.getSWFVersion()));
-    return v;
-}
-
-/// Force type to bool.
-as_value&
-convertToBoolean(as_value& v, const VM& vm)
-{
-    v.set_bool(v.to_bool(vm.getSWFVersion()));
-    return v;
-}
-
-as_value&
-convertToPrimitive(as_value& v, const VM& vm)
-{
-    const as_value::AsType t(v.defaultPrimitive(vm.getSWFVersion()));
-    v = v.to_primitive(t);
-    return v;
-}
-
 namespace {
 
 /// Checks for equality between an object value and a primitive value
diff --git a/libcore/as_value.h b/libcore/as_value.h
index 06c05f4..f04a471 100644
--- a/libcore/as_value.h
+++ b/libcore/as_value.h
@@ -475,18 +475,6 @@ private:
     
 };
 
-/// Force type to number.
-as_value& convertToNumber(as_value& v, const VM& vm);
-
-/// Force type to string.
-as_value& convertToString(as_value& v, const VM& vm);
-
-/// Force type to bool.
-as_value& convertToBoolean(as_value& v, const VM& vm);
-
-/// Convert to primitive type
-as_value& convertToPrimitive(as_value& v, const VM& vm);
-
 /// Stream operator.
 std::ostream& operator<<(std::ostream& os, const as_value& v);
 
diff --git a/libcore/vm/VM.cpp b/libcore/vm/VM.cpp
index 0eb26fc..a963a25 100644
--- a/libcore/vm/VM.cpp
+++ b/libcore/vm/VM.cpp
@@ -517,6 +517,39 @@ toNumber(const as_value& v, const VM& vm)
     return v.to_number(vm.getSWFVersion());
 }
 
+/// Force type to number.
+as_value&
+convertToNumber(as_value& v, const VM& vm)
+{
+    v.set_double(v.to_number(vm.getSWFVersion()));
+    return v;
+}
+
+/// Force type to string.
+as_value&
+convertToString(as_value& v, const VM& vm)
+{
+    v.set_string(v.to_string(vm.getSWFVersion()));
+    return v;
+}
+
+/// Force type to bool.
+as_value&
+convertToBoolean(as_value& v, const VM& vm)
+{
+    v.set_bool(v.to_bool(vm.getSWFVersion()));
+    return v;
+}
+
+as_value&
+convertToPrimitive(as_value& v, const VM& vm)
+{
+    const as_value::AsType t(v.defaultPrimitive(vm.getSWFVersion()));
+    v = v.to_primitive(t);
+    return v;
+}
+
+
 } // end of namespace gnash
 
 
diff --git a/libcore/vm/VM.h b/libcore/vm/VM.h
index 8fde5fe..bd3266d 100644
--- a/libcore/vm/VM.h
+++ b/libcore/vm/VM.h
@@ -425,10 +425,24 @@ void subtract(as_value& op1, const as_value& op2, const 
VM& vm);
 /// @param vm       The VM executing the operation.
 as_value newLessThan(const as_value& op1, const as_value& op2, const VM& vm);
 
+/// Convert an as_value to boolean type
 bool toBool(const as_value& v, const VM& vm);
 
+/// Convert an as_value to number type
 double toNumber(const as_value& v, const VM& vm);
 
+/// Force type to number.
+as_value& convertToNumber(as_value& v, const VM& vm);
+
+/// Force type to string.
+as_value& convertToString(as_value& v, const VM& vm);
+
+/// Force type to bool.
+as_value& convertToBoolean(as_value& v, const VM& vm);
+
+/// Convert to primitive type
+as_value& convertToPrimitive(as_value& v, const VM& vm);
+
 } // namespace gnash
 
 #endif // GNASH_VM_H

http://git.savannah.gnu.org/cgit//commit/?id=46cf89e6467bc1a96f7e7e11089f51d19d9b88e8


commit 46cf89e6467bc1a96f7e7e11089f51d19d9b88e8
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 08:26:02 2010 +0200

    Drop all to_number() use outside as_value.

diff --git a/libcore/asobj/Array_as.cpp b/libcore/asobj/Array_as.cpp
index 2d309f2..ce4cba8 100644
--- a/libcore/asobj/Array_as.cpp
+++ b/libcore/asobj/Array_as.cpp
@@ -306,73 +306,72 @@ sortIndexed(as_object& array, AVCMP avc)
 // string comparison, ascending (default sort method)
 struct as_value_lt
 {
-    int _version;
+    as_value_lt(const fn_call& fn) : _fn(fn) {}
 
-    as_value_lt(int version) : _version(version) {}
-
-    inline int str_cmp(const as_value& a, const as_value& b)
+    int str_cmp(const as_value& a, const as_value& b) const 
     {
-        std::string s = a.to_string(_version);
-        return s.compare(b.to_string(_version));
+        std::string s = a.to_string(getSWFVersion(_fn));
+        return s.compare(b.to_string(getSWFVersion(_fn)));
     }
 
-    inline int str_nocase_cmp(const as_value& a, const as_value& b)
+    int str_nocase_cmp(const as_value& a, const as_value& b) const
     {
         using namespace boost::algorithm;
 
-        std::string c = to_upper_copy(a.to_string(_version));
-        std::string d = to_upper_copy(b.to_string(_version));
+        std::string c = to_upper_copy(a.to_string(getSWFVersion(_fn)));
+        std::string d = to_upper_copy(b.to_string(getSWFVersion(_fn)));
         return c.compare(d);
     }
 
-    inline bool as_value_numLT (const as_value& a, const as_value& b)
+    bool as_value_numLT(const as_value& a, const as_value& b) const
     {
         if (a.is_undefined()) return false;
         if (b.is_undefined()) return true;
         if (a.is_null()) return false;
         if (b.is_null()) return true;
-        double aval = a.to_number();
-        double bval = b.to_number();
+        const double aval = toNumber(a, getVM(_fn));
+        const double bval = toNumber(b, getVM(_fn));
         if (isNaN(aval)) return false;
         if (isNaN(bval)) return true;
         return aval < bval;
     }
 
-    inline bool as_value_numGT (const as_value& a, const as_value& b)
+    bool as_value_numGT(const as_value& a, const as_value& b) const
     {
         if (b.is_undefined()) return false;
         if (a.is_undefined()) return true;
         if (b.is_null()) return false;
         if (a.is_null()) return true;
-        double aval = a.to_number();
-        double bval = b.to_number();
+        const double aval = toNumber(a, getVM(_fn));
+        const double bval = toNumber(b, getVM(_fn));
         if (isNaN(bval)) return false;
         if (isNaN(aval)) return true;
         return aval > bval;
     }
 
-    inline bool as_value_numEQ (const as_value& a, const as_value& b)
+    inline bool as_value_numEQ(const as_value& a, const as_value& b) const
     {
         if (a.is_undefined() && b.is_undefined()) return true;
         if (a.is_null() && b.is_null()) return true;
-        double aval = a.to_number();
-        double bval = b.to_number();
+        double aval = toNumber(a, getVM(_fn));
+        double bval = toNumber(b, getVM(_fn));
         if (isNaN(aval) && isNaN(bval)) return true;
         return aval == bval;
     }
 
-    bool operator() (const as_value& a, const as_value& b)
+    bool operator()(const as_value& a, const as_value& b) const
     {
         return str_cmp(a, b) < 0;
     }
+private:
+    const fn_call& _fn;
 };
 
 // string comparison, descending
 struct as_value_gt : public as_value_lt 
 {
-    as_value_gt(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
-    {
+    as_value_gt(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const {
         return str_cmp(a, b) > 0;
     }
 };
@@ -380,8 +379,8 @@ struct as_value_gt : public as_value_lt
 // string equality
 struct as_value_eq : public as_value_lt
 {
-    as_value_eq(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_eq(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
         return str_cmp(a, b) == 0;
     }
@@ -390,8 +389,8 @@ struct as_value_eq : public as_value_lt
 // case-insensitive string comparison, ascending
 struct as_value_nocase_lt : public as_value_lt
 {
-    as_value_nocase_lt(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_nocase_lt(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
         return str_nocase_cmp(a, b) < 0;
     }
@@ -400,8 +399,8 @@ struct as_value_nocase_lt : public as_value_lt
 // case-insensitive string comparison, descending
 struct as_value_nocase_gt : public as_value_lt
 {
-    as_value_nocase_gt(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_nocase_gt(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
         return str_nocase_cmp(a, b) > 0;
     }
@@ -410,8 +409,8 @@ struct as_value_nocase_gt : public as_value_lt
 // case-insensitive string equality
 struct as_value_nocase_eq : public as_value_lt
 {
-    as_value_nocase_eq(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_nocase_eq(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
         return str_nocase_cmp(a, b) == 0;
     }
@@ -420,11 +419,10 @@ struct as_value_nocase_eq : public as_value_lt
 // numeric comparison, ascending
 struct as_value_num_lt : public as_value_lt
 {
-    as_value_num_lt(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_num_lt(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
-        if (a.is_string() || b.is_string())
-            return str_cmp(a, b) < 0;
+        if (a.is_string() || b.is_string()) return str_cmp(a, b) < 0;
         return as_value_numLT(a, b);
     }
 };
@@ -432,11 +430,10 @@ struct as_value_num_lt : public as_value_lt
 // numeric comparison, descending
 struct as_value_num_gt : public as_value_lt
 {
-    as_value_num_gt(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_num_gt(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
-        if (a.is_string() || b.is_string())
-            return str_cmp(a, b) > 0;
+        if (a.is_string() || b.is_string()) return str_cmp(a, b) > 0;
         return as_value_numGT(a, b);
     }
 };
@@ -444,11 +441,10 @@ struct as_value_num_gt : public as_value_lt
 // numeric equality
 struct as_value_num_eq : public as_value_lt
 {
-    as_value_num_eq(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_num_eq(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
-        if (a.is_string() || b.is_string())
-            return str_cmp(a, b) == 0;
+        if (a.is_string() || b.is_string()) return str_cmp(a, b) == 0;
         return as_value_numEQ(a, b);
     }
 };
@@ -456,11 +452,10 @@ struct as_value_num_eq : public as_value_lt
 // case-insensitive numeric comparison, ascending
 struct as_value_num_nocase_lt : public as_value_lt
 {
-    as_value_num_nocase_lt(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_num_nocase_lt(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
-        if (a.is_string() || b.is_string())
-            return str_nocase_cmp(a, b) < 0;
+        if (a.is_string() || b.is_string()) return str_nocase_cmp(a, b) < 0;
         return as_value_numLT(a, b);
     }
 };
@@ -468,11 +463,10 @@ struct as_value_num_nocase_lt : public as_value_lt
 // case-insensitive numeric comparison, descending
 struct as_value_num_nocase_gt : public as_value_lt
 {
-    as_value_num_nocase_gt(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_num_nocase_gt(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator()(const as_value& a, const as_value& b) const
     {
-        if (a.is_string() || b.is_string())
-            return str_nocase_cmp(a, b) > 0;
+        if (a.is_string() || b.is_string()) return str_nocase_cmp(a, b) > 0;
         return as_value_numGT(a, b);
     }
 };
@@ -480,11 +474,10 @@ struct as_value_num_nocase_gt : public as_value_lt
 // case-insensitive numeric equality
 struct as_value_num_nocase_eq : public as_value_lt
 {
-    as_value_num_nocase_eq(int version) : as_value_lt(version) {}
-    bool operator() (const as_value& a, const as_value& b)
+    as_value_num_nocase_eq(const fn_call& fn) : as_value_lt(fn) {}
+    bool operator() (const as_value& a, const as_value& b) const
     {
-        if (a.is_string() || b.is_string())
-            return str_nocase_cmp(a, b) == 0;
+        if (a.is_string() || b.is_string()) return str_nocase_cmp(a, b) == 0;
         return as_value_numEQ(a, b);
     }
 };
@@ -493,7 +486,7 @@ struct as_value_num_nocase_eq : public as_value_lt
 // Note:
 // SORT_UNIQUE and SORT_RETURN_INDEX must first be stripped from the flag
 as_cmp_fn
-get_basic_cmp(boost::uint8_t flags, int version)
+get_basic_cmp(boost::uint8_t flags, const fn_call& fn)
 {
     as_cmp_fn f;
 
@@ -504,44 +497,44 @@ get_basic_cmp(boost::uint8_t flags, int version)
     switch ( flags )
     {
         case 0: // default string comparison
-            f = as_value_lt(version);
+            f = as_value_lt(fn);
             return f;
 
         case SORT_DESCENDING:
-            f = as_value_gt(version);
+            f = as_value_gt(fn);
             return f;
 
         case SORT_CASE_INSENSITIVE: 
-            f = as_value_nocase_lt(version);
+            f = as_value_nocase_lt(fn);
             return f;
 
         case SORT_CASE_INSENSITIVE | 
                 SORT_DESCENDING:
-            f = as_value_nocase_gt(version);
+            f = as_value_nocase_gt(fn);
             return f;
 
         case SORT_NUMERIC: 
-            f = as_value_num_lt(version);
+            f = as_value_num_lt(fn);
             return f;
 
         case SORT_NUMERIC | SORT_DESCENDING:
-            f = as_value_num_gt(version);
+            f = as_value_num_gt(fn);
             return f;
 
         case SORT_CASE_INSENSITIVE | 
                 SORT_NUMERIC:
-            f = as_value_num_nocase_lt(version);
+            f = as_value_num_nocase_lt(fn);
             return f;
 
         case SORT_CASE_INSENSITIVE | 
                 SORT_NUMERIC |
                 SORT_DESCENDING:
-            f = as_value_num_nocase_gt(version);
+            f = as_value_num_nocase_gt(fn);
             return f;
 
         default:
-            log_unimpl(_("Unhandled sort flags: %d (0x%X)"), (int)flags, 
(int)flags);
-            f = as_value_lt(version);
+            log_unimpl(_("Unhandled sort flags: %d (0x%X)"), +flags, +flags);
+            f = as_value_lt(fn);
             return f;
     }
 }
@@ -550,32 +543,32 @@ get_basic_cmp(boost::uint8_t flags, int version)
 // Note:
 // SORT_UNIQUE and SORT_RETURN_INDEX must first be stripped from the flag
 as_cmp_fn
-get_basic_eq(boost::uint8_t flags, int version)
+get_basic_eq(boost::uint8_t flags, const fn_call& fn)
 {
     as_cmp_fn f;
     flags &= ~(SORT_DESCENDING);
 
-    switch ( flags )
+    switch (flags)
     {
         case 0: // default string comparison
-            f = as_value_eq(version);
+            f = as_value_eq(fn);
             return f;
 
         case SORT_CASE_INSENSITIVE: 
-            f = as_value_nocase_eq(version);
+            f = as_value_nocase_eq(fn);
             return f;
 
         case SORT_NUMERIC: 
-            f = as_value_num_eq(version);
+            f = as_value_num_eq(fn);
             return f;
 
         case SORT_CASE_INSENSITIVE | 
                 SORT_NUMERIC:
-            f = as_value_num_nocase_eq(version);
+            f = as_value_num_nocase_eq(fn);
             return f;
 
         default:
-            f = as_value_eq(version);
+            f = as_value_eq(fn);
             return f;
     }
 }
@@ -1007,10 +1000,8 @@ array_sort(const fn_call& fn)
 {
     as_object* array = ensure<ValidThis>(fn);
     
-    const int version = getSWFVersion(*array);
-    
     if (!fn.nargs) {
-        sort(*array, as_value_lt(version));
+        sort(*array, as_value_lt(fn));
         return as_value(array);
     }
     
@@ -1060,10 +1051,10 @@ array_sort(const fn_call& fn)
 
     bool do_unique, do_index;
     flags = flag_preprocess(flags, &do_unique, &do_index);
-    as_cmp_fn comp = get_basic_cmp(flags, version);
+    as_cmp_fn comp = get_basic_cmp(flags, fn);
 
     if (do_unique) {
-        as_cmp_fn eq = get_basic_eq(flags, version);
+        as_cmp_fn eq = get_basic_eq(flags, fn);
         if (do_index) return sortIndexed(*array, comp, eq);
         return sort(*array, comp, eq) ? as_value(array) : as_value(0.0);
     }
@@ -1096,11 +1087,11 @@ array_sortOn(const fn_call& fn)
             flags = flag_preprocess(flags, &do_unique, &do_index);
         }
 
-        as_value_prop avc(propField, get_basic_cmp(flags, version),
+        as_value_prop avc(propField, get_basic_cmp(flags, fn),
                 getGlobal(fn));
 
         if (do_unique) {
-            as_value_prop ave(propField, get_basic_eq(flags, version), 
+            as_value_prop ave(propField, get_basic_eq(flags, fn), 
                     getGlobal(fn));
             if (do_index)
                 return sortIndexed(*array, avc, ave);
@@ -1134,7 +1125,7 @@ array_sortOn(const fn_call& fn)
         // case: sortOn(["prop1", "prop2"])
         if (fn.nargs == 1) {
             // assign each cmp function to the standard cmp fn
-            as_cmp_fn c = get_basic_cmp(0, version);
+            as_cmp_fn c = get_basic_cmp(0, fn);
             cmp.assign(optnum, c);
         }
         // case: sortOn(["prop1", "prop2"], [Array.FLAG1, Array.FLAG2])
@@ -1155,17 +1146,17 @@ array_sortOn(const fn_call& fn)
                     flgs.begin();
 
                 while (it != flgs.end()) {
-                    cmp.push_back(get_basic_cmp(*it++, version));
+                    cmp.push_back(get_basic_cmp(*it++, fn));
                 }
 
                 if (do_unique) {
                     it = flgs.begin();
                     while (it != flgs.end())
-                        eq.push_back(get_basic_eq(*it++, version));
+                        eq.push_back(get_basic_eq(*it++, fn));
                 }
             }
             else {
-                as_cmp_fn c = get_basic_cmp(0, version);
+                as_cmp_fn c = get_basic_cmp(0, fn);
                 cmp.assign(optnum, c);
             }
         }
@@ -1174,12 +1165,12 @@ array_sortOn(const fn_call& fn)
             boost::uint8_t flags = 
                 static_cast<boost::uint8_t>(toInt(fn.arg(1)));
             flags = flag_preprocess(flags, &do_unique, &do_index);
-            as_cmp_fn c = get_basic_cmp(flags, version);
+            as_cmp_fn c = get_basic_cmp(flags, fn);
 
             cmp.assign(optnum, c);
             
             if (do_unique) {
-                as_cmp_fn e = get_basic_eq(flags, version);
+                as_cmp_fn e = get_basic_eq(flags, fn);
                 eq.assign(optnum, e);
             }
         }
diff --git a/libcore/asobj/Math_as.cpp b/libcore/asobj/Math_as.cpp
index ef2ad3d..b92e520 100644
--- a/libcore/asobj/Math_as.cpp
+++ b/libcore/asobj/Math_as.cpp
@@ -99,8 +99,7 @@ namespace {
 //
 
 // If it is called with two arguments, the valueOf method
-// (i.e. to_number()) of the second method is called, but 
-// not used. Strange, but true.
+// of the second method is called, but not used. Strange, but true.
 template<UnaryMathFunc Func>
 as_value
 unaryFunction(const fn_call& fn)

http://git.savannah.gnu.org/cgit//commit/?id=891a392ba637f6162b4b809ab23d7b7e649b21d8


commit 891a392ba637f6162b4b809ab23d7b7e649b21d8
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 08:13:54 2010 +0200

    More toNumber.

diff --git a/libcore/asobj/ASConversions.cpp b/libcore/asobj/ASConversions.cpp
index ff2bba1..ee700e9 100644
--- a/libcore/asobj/ASConversions.cpp
+++ b/libcore/asobj/ASConversions.cpp
@@ -44,14 +44,16 @@ namespace {
 SWFMatrix
 toSWFMatrix(as_object& m)
 {
+    VM& vm = getVM(m);
+
     // This is case sensitive.
     if (getMember(m, NSV::PROP_MATRIX_TYPE).to_string() == "box") {
         
-        const double x = pixelsToTwips(getMember(m, NSV::PROP_X).to_number());
-        const double y = pixelsToTwips(getMember(m, NSV::PROP_Y).to_number());
-        const double w = pixelsToTwips(getMember(m, NSV::PROP_W).to_number());
-        const double h = pixelsToTwips(getMember(m, NSV::PROP_H).to_number()); 
-        const double r = getMember(m, NSV::PROP_R).to_number();
+        const double x = pixelsToTwips(toNumber(getMember(m, NSV::PROP_X), 
vm));
+        const double y = pixelsToTwips(toNumber(getMember(m, NSV::PROP_Y), 
vm));
+        const double w = pixelsToTwips(toNumber(getMember(m, NSV::PROP_W), 
vm));
+        const double h = pixelsToTwips(toNumber(getMember(m, NSV::PROP_H), 
vm)); 
+        const double r = toNumber(getMember(m, NSV::PROP_R), vm);
         const double a = std::cos(r) * w * 2;
         const double b = std::sin(r) * h * 2;
         const double c = -std::sin(r) * w * 2;
@@ -63,18 +65,18 @@ toSWFMatrix(as_object& m)
 
     // Convert input matrix to SWFMatrix.
     const boost::int32_t a = truncateWithFactor<65536>(
-            getMember(m, NSV::PROP_A).to_number());
+            toNumber(getMember(m, NSV::PROP_A), vm));
     const boost::int32_t b = truncateWithFactor<65536>(
-            getMember(m, NSV::PROP_B).to_number());
+            toNumber(getMember(m, NSV::PROP_B), vm));
     const boost::int32_t c = truncateWithFactor<65536>(
-            getMember(m, NSV::PROP_C).to_number());
+            toNumber(getMember(m, NSV::PROP_C), vm));
     const boost::int32_t d = truncateWithFactor<65536>(
-            getMember(m, NSV::PROP_D).to_number());
+            toNumber(getMember(m, NSV::PROP_D), vm));
 
     const boost::int32_t tx = pixelsToTwips(
-            getMember(m, NSV::PROP_TX).to_number());
+            toNumber(getMember(m, NSV::PROP_TX), vm));
     const boost::int32_t ty = pixelsToTwips(
-            getMember(m, NSV::PROP_TY).to_number());
+            toNumber(getMember(m, NSV::PROP_TY), vm));
     return SWFMatrix(a, b, c, d, tx, ty);
 
 }
diff --git a/libcore/asobj/Color_as.cpp b/libcore/asobj/Color_as.cpp
index abb3212..53cb837 100644
--- a/libcore/asobj/Color_as.cpp
+++ b/libcore/asobj/Color_as.cpp
@@ -252,14 +252,14 @@ color_ctor(const fn_call& fn)
 }
 
 inline void
-parseColorTransProp (as_object& obj, string_table::key key, boost::int16_t&
+parseColorTransProp(as_object& obj, string_table::key key, boost::int16_t&
         target, bool scale)
 {
        as_value tmp;
        if (!obj.get_member(key, &tmp)) return;
     
-       const double d = tmp.to_number();
-       if ( scale ) {   
+       const double d = toNumber(tmp, getVM(obj));
+       if (scale) {   
         target = static_cast<boost::int16_t>(d * 2.56);
     }
        else {
diff --git a/libcore/asobj/flash/filters/BevelFilter_as.cpp 
b/libcore/asobj/flash/filters/BevelFilter_as.cpp
index 4d8bc1b..64d69db 100644
--- a/libcore/asobj/flash/filters/BevelFilter_as.cpp
+++ b/libcore/asobj/flash/filters/BevelFilter_as.cpp
@@ -124,7 +124,7 @@ bevelfilter_highlightColor(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_highlightColor );
     }
-    boost::uint32_t sp_highlightColor = fn.arg(0).to_number ();
+    boost::uint32_t sp_highlightColor = toNumber(fn.arg(0), getVM(fn));
     ptr->m_highlightColor = sp_highlightColor;
     return as_value();
 }
@@ -136,7 +136,7 @@ bevelfilter_highlightAlpha(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_highlightAlpha );
     }
-    boost::uint8_t sp_highlightAlpha = fn.arg(0).to_number ();
+    boost::uint8_t sp_highlightAlpha = toNumber(fn.arg(0), getVM(fn));
     ptr->m_highlightAlpha = sp_highlightAlpha;
     return as_value();
 }
@@ -148,7 +148,7 @@ bevelfilter_shadowColor(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_shadowColor );
     }
-    boost::uint32_t sp_shadowColor = fn.arg(0).to_number ();
+    boost::uint32_t sp_shadowColor = toNumber(fn.arg(0), getVM(fn));
     ptr->m_shadowColor = sp_shadowColor;
     return as_value();
 }
@@ -160,7 +160,7 @@ bevelfilter_shadowAlpha(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_shadowAlpha );
     }
-    boost::uint8_t sp_shadowAlpha = fn.arg(0).to_number ();
+    boost::uint8_t sp_shadowAlpha = toNumber(fn.arg(0), getVM(fn));
     ptr->m_shadowAlpha = sp_shadowAlpha;
     return as_value();
 }
@@ -172,7 +172,7 @@ bevelfilter_blurX(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_blurX );
     }
-    float sp_blurX = fn.arg(0).to_number ();
+    float sp_blurX = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurX = sp_blurX;
     return as_value();
 }
@@ -184,7 +184,7 @@ bevelfilter_blurY(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_blurY );
     }
-    float sp_blurY = fn.arg(0).to_number ();
+    float sp_blurY = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurY = sp_blurY;
     return as_value();
 }
@@ -196,7 +196,7 @@ bevelfilter_strength(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_strength );
     }
-    float sp_strength = fn.arg(0).to_number ();
+    float sp_strength = toNumber(fn.arg(0), getVM(fn));
     ptr->m_strength = sp_strength;
     return as_value();
 }
@@ -208,7 +208,7 @@ bevelfilter_quality(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_quality );
     }
-    boost::uint8_t sp_quality = fn.arg(0).to_number ();
+    boost::uint8_t sp_quality = toNumber(fn.arg(0), getVM(fn));
     ptr->m_quality = sp_quality;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/BlurFilter_as.cpp 
b/libcore/asobj/flash/filters/BlurFilter_as.cpp
index 0cb7d89..e66cd38 100644
--- a/libcore/asobj/flash/filters/BlurFilter_as.cpp
+++ b/libcore/asobj/flash/filters/BlurFilter_as.cpp
@@ -67,7 +67,7 @@ blurfilter_blurX(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_blurX );
     }
-    float sp_blurX = fn.arg(0).to_number ();
+    float sp_blurX = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurX = sp_blurX;
     return as_value();
 }
@@ -79,7 +79,7 @@ blurfilter_blurY(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_blurY );
     }
-    float sp_blurY = fn.arg(0).to_number ();
+    float sp_blurY = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurY = sp_blurY;
     return as_value();
 }
@@ -91,7 +91,7 @@ blurfilter_quality(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_quality );
     }
-    boost::uint8_t sp_quality = fn.arg(0).to_number ();
+    boost::uint8_t sp_quality = toNumber(fn.arg(0), getVM(fn));
     ptr->m_quality = sp_quality;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/DropShadowFilter_as.cpp 
b/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
index a70c11d..43663f4 100644
--- a/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
+++ b/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
@@ -145,7 +145,7 @@ dropshadowfilter_blurX(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_blurX );
     }
-    float sp_blurX = fn.arg(0).to_number ();
+    float sp_blurX = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurX = sp_blurX;
     return as_value();
 }
@@ -157,7 +157,7 @@ dropshadowfilter_blurY(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_blurY );
     }
-    float sp_blurY = fn.arg(0).to_number ();
+    float sp_blurY = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurY = sp_blurY;
     return as_value();
 }
@@ -169,7 +169,7 @@ dropshadowfilter_strength(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_strength );
     }
-    float sp_strength = fn.arg(0).to_number ();
+    float sp_strength = toNumber(fn.arg(0), getVM(fn));
     ptr->m_strength = sp_strength;
     return as_value();
 }
@@ -181,7 +181,7 @@ dropshadowfilter_quality(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_quality );
     }
-    boost::uint8_t sp_quality = fn.arg(0).to_number ();
+    boost::uint8_t sp_quality = toNumber(fn.arg(0), getVM(fn));
     ptr->m_quality = sp_quality;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/GlowFilter_as.cpp 
b/libcore/asobj/flash/filters/GlowFilter_as.cpp
index ac3140f..7e6fac8 100644
--- a/libcore/asobj/flash/filters/GlowFilter_as.cpp
+++ b/libcore/asobj/flash/filters/GlowFilter_as.cpp
@@ -87,7 +87,7 @@ glowfilter_inner(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_inner );
     }
-    boost::uint32_t sp_inner = fn.arg(0).to_number ();
+    boost::uint32_t sp_inner = toNumber(fn.arg(0), getVM(fn));
     ptr->m_inner = sp_inner;
     return as_value();
 }
@@ -99,7 +99,7 @@ glowfilter_color(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_color );
     }
-    float sp_color = fn.arg(0).to_number ();
+    float sp_color = toNumber(fn.arg(0), getVM(fn));
     ptr->m_color = sp_color;
     return as_value();
 }
@@ -111,7 +111,7 @@ glowfilter_alpha(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_alpha );
     }
-    float sp_alpha = fn.arg(0).to_number ();
+    float sp_alpha = toNumber(fn.arg(0), getVM(fn));
     ptr->m_alpha = sp_alpha;
     return as_value();
 }
@@ -123,7 +123,7 @@ glowfilter_blurX(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_blurX );
     }
-    float sp_blurX = fn.arg(0).to_number ();
+    float sp_blurX = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurX = sp_blurX;
     return as_value();
 }
@@ -135,7 +135,7 @@ glowfilter_blurY(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_blurY );
     }
-    float sp_blurY = fn.arg(0).to_number ();
+    float sp_blurY = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurY = sp_blurY;
     return as_value();
 }
@@ -147,7 +147,7 @@ glowfilter_strength(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_strength );
     }
-    float sp_strength = fn.arg(0).to_number ();
+    float sp_strength = toNumber(fn.arg(0), getVM(fn));
     ptr->m_strength = sp_strength;
     return as_value();
 }
@@ -159,7 +159,7 @@ glowfilter_quality(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_quality );
     }
-    boost::uint8_t sp_quality = fn.arg(0).to_number ();
+    boost::uint8_t sp_quality = toNumber(fn.arg(0), getVM(fn));
     ptr->m_quality = sp_quality;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp 
b/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
index e07b6ae..214c760 100644
--- a/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
+++ b/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
@@ -145,7 +145,7 @@ gradientbevelfilter_blurX(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_blurX );
     }
-    float sp_blurX = fn.arg(0).to_number ();
+    float sp_blurX = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurX = sp_blurX;
     return as_value();
 }
@@ -157,7 +157,7 @@ gradientbevelfilter_blurY(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_blurY );
     }
-    float sp_blurY = fn.arg(0).to_number ();
+    float sp_blurY = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurY = sp_blurY;
     return as_value();
 }
@@ -169,7 +169,7 @@ gradientbevelfilter_strength(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_strength );
     }
-    float sp_strength = fn.arg(0).to_number ();
+    float sp_strength = toNumber(fn.arg(0), getVM(fn));
     ptr->m_strength = sp_strength;
     return as_value();
 }
@@ -181,7 +181,7 @@ gradientbevelfilter_quality(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_quality );
     }
-    boost::uint8_t sp_quality = fn.arg(0).to_number ();
+    boost::uint8_t sp_quality = toNumber(fn.arg(0), getVM(fn));
     ptr->m_quality = sp_quality;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp 
b/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
index d85c2a2..1797244 100644
--- a/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
+++ b/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
@@ -146,7 +146,7 @@ gradientglowfilter_blurX(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_blurX );
     }
-    float sp_blurX = fn.arg(0).to_number ();
+    float sp_blurX = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurX = sp_blurX;
     return as_value();
 }
@@ -158,7 +158,7 @@ gradientglowfilter_blurY(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_blurY );
     }
-    float sp_blurY = fn.arg(0).to_number ();
+    float sp_blurY = toNumber(fn.arg(0), getVM(fn));
     ptr->m_blurY = sp_blurY;
     return as_value();
 }
@@ -170,7 +170,7 @@ gradientglowfilter_strength(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_strength );
     }
-    float sp_strength = fn.arg(0).to_number ();
+    float sp_strength = toNumber(fn.arg(0), getVM(fn));
     ptr->m_strength = sp_strength;
     return as_value();
 }
@@ -182,7 +182,7 @@ gradientglowfilter_quality(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_quality );
     }
-    boost::uint8_t sp_quality = fn.arg(0).to_number ();
+    boost::uint8_t sp_quality = toNumber(fn.arg(0), getVM(fn));
     ptr->m_quality = sp_quality;
     return as_value();
 }

http://git.savannah.gnu.org/cgit//commit/?id=586fdd79ab7a758fd1a7850a76fd65a2ccca1fd5


commit 586fdd79ab7a758fd1a7850a76fd65a2ccca1fd5
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 08:06:32 2010 +0200

    More toNumber.

diff --git a/libcore/asobj/flash/geom/Matrix_as.cpp 
b/libcore/asobj/flash/geom/Matrix_as.cpp
index 5e70c01..92da3f3 100644
--- a/libcore/asobj/flash/geom/Matrix_as.cpp
+++ b/libcore/asobj/flash/geom/Matrix_as.cpp
@@ -86,8 +86,7 @@ namespace {
     as_value matrix_transformPoint(const fn_call& fn);
     as_value matrix_translate(const fn_call& fn);
     void fillMatrix(MatrixType& matrix, as_object& matrixObject);
-    PointType transformPoint(as_object* const pointObject,
-            as_object* const matrixObject);
+    PointType transformPoint(as_object& pointObject, as_object& matrixObject);
 
     as_value get_flash_geom_matrix_constructor(const fn_call& fn);
     as_value matrix_ctor(const fn_call& fn);
@@ -408,7 +407,7 @@ matrix_deltaTransformPoint(const fn_call& fn)
     as_object* obj = arg.to_object(getGlobal(fn));
     assert(obj);
 
-    const PointType& point = transformPoint(obj, ptr);
+    const PointType& point = transformPoint(*obj, *ptr);
 
     // Construct a Point and set its properties.
     as_value pointClass(fn.env().find_object("flash.geom.Point"));
@@ -545,10 +544,10 @@ matrix_rotate(const fn_call& fn)
     ptr->get_member(NSV::PROP_TX, &tx);
     ptr->get_member(NSV::PROP_TY, &ty);
             
-    currentMatrix(0, 0) = a.to_number();
-    currentMatrix(0, 1) = b.to_number();
-    currentMatrix(1, 0) = c.to_number();
-    currentMatrix(1, 1) = d.to_number();
+    currentMatrix(0, 0) = toNumber(a, getVM(fn));
+    currentMatrix(0, 1) = toNumber(b, getVM(fn));
+    currentMatrix(1, 0) = toNumber(c, getVM(fn));
+    currentMatrix(1, 1) = toNumber(d, getVM(fn));
 
 #ifdef GNASH_DEBUG_GEOM_MATRIX
     log_debug("(Matrix.rotate) This matrix (pre-transform): %s", 
currentMatrix);
@@ -569,8 +568,8 @@ matrix_rotate(const fn_call& fn)
 
     // Do rotation separately.
     PointType translation;
-    translation(0) = tx.to_number();
-    translation(1) = ty.to_number();
+    translation(0) = toNumber(tx, getVM(fn));
+    translation(1) = toNumber(ty, getVM(fn));
     
     translation = boost::numeric::ublas::prod(translation, transformMatrix);
 
@@ -620,10 +619,10 @@ matrix_scale(const fn_call& fn)
     ptr->get_member(NSV::PROP_TX, &tx);
     ptr->get_member(NSV::PROP_TY, &ty);
             
-    currentMatrix(0, 0) = a.to_number();
-    currentMatrix(0, 1) = b.to_number();
-    currentMatrix(1, 0) = c.to_number();
-    currentMatrix(1, 1) = d.to_number();
+    currentMatrix(0, 0) = toNumber(a, getVM(fn));
+    currentMatrix(0, 1) = toNumber(b, getVM(fn));
+    currentMatrix(1, 0) = toNumber(c, getVM(fn));
+    currentMatrix(1, 1) = toNumber(d, getVM(fn));
     
 #ifdef GNASH_DEBUG_GEOM_MATRIX
     log_debug("(Matrix.scale) This matrix (pre-transform): %s", currentMatrix);
@@ -643,8 +642,8 @@ matrix_scale(const fn_call& fn)
     ptr->set_member(NSV::PROP_D, currentMatrix(1, 1));
 
     // This is just a simple multiplication, so do it separately.
-    ptr->set_member(NSV::PROP_TX, as_value(tx.to_number() * scaleX));
-    ptr->set_member(NSV::PROP_TY, as_value(ty.to_number() * scaleY));  
+    ptr->set_member(NSV::PROP_TX, as_value(toNumber(tx, getVM(fn)) * scaleX));
+    ptr->set_member(NSV::PROP_TY, as_value(toNumber(ty, getVM(fn)) * scaleY)); 
 
 
     return as_value();
 }
@@ -730,7 +729,7 @@ matrix_transformPoint(const fn_call& fn)
     ptr->get_member(NSV::PROP_TX, &tx);
     ptr->get_member(NSV::PROP_TY, &ty);
     
-    const PointType& point = transformPoint(obj, ptr);
+    const PointType& point = transformPoint(*obj, *ptr);
 
     // Construct a Point and set its properties.
     as_value pointClass(fn.env().find_object("flash.geom.Point"));
@@ -743,7 +742,7 @@ matrix_transformPoint(const fn_call& fn)
     }
 
     fn_call::Args args;
-    args += point(0) + tx.to_number(), point(1) + ty.to_number();
+    args += point(0) + toNumber(tx, getVM(fn)), point(1) + toNumber(ty, 
getVM(fn));
 
     as_value ret = constructInstance(*pointCtor, fn.env(), args);
 
@@ -774,8 +773,8 @@ matrix_translate(const fn_call& fn)
         ptr->get_member(NSV::PROP_TX, &tx);
         ptr->get_member(NSV::PROP_TY, &ty);
 
-        double transX = toNumber(fn.arg(0), getVM(fn)) + tx.to_number();
-        double transY = toNumber(fn.arg(1), getVM(fn)) + ty.to_number();
+        double transX = toNumber(fn.arg(0), getVM(fn)) + toNumber(tx, 
getVM(fn));
+        double transY = toNumber(fn.arg(1), getVM(fn)) + toNumber(ty, 
getVM(fn));
                 
         ptr->set_member(NSV::PROP_TX, as_value(transX));
         ptr->set_member(NSV::PROP_TY, as_value(transY));
@@ -788,53 +787,46 @@ matrix_translate(const fn_call& fn)
 // (transformPoint) or not if not (deltaTransformPoint). Just
 // make sure the objects are what they're supposed to be.
 PointType
-transformPoint(as_object* const pointObject, as_object* const matrixObject)
+transformPoint(as_object& pointObject, as_object& matrixObject)
 {
     // Get the point co-ordinates.
     as_value x, y;
     
-    pointObject->get_member(NSV::PROP_X, &x);
-    pointObject->get_member(NSV::PROP_Y, &y);
+    pointObject.get_member(NSV::PROP_X, &x);
+    pointObject.get_member(NSV::PROP_Y, &y);
 
     // Get the matrix elements to use as a transformation matrix.
     as_value a, b, c, d;
 
-    matrixObject->get_member(NSV::PROP_A, &a);
-    matrixObject->get_member(NSV::PROP_B, &b);
-    matrixObject->get_member(NSV::PROP_C, &c);
-    matrixObject->get_member(NSV::PROP_D, &d);
+    matrixObject.get_member(NSV::PROP_A, &a);
+    matrixObject.get_member(NSV::PROP_B, &b);
+    matrixObject.get_member(NSV::PROP_C, &c);
+    matrixObject.get_member(NSV::PROP_D, &d);
+
+    VM& vm = getVM(pointObject);
 
     // Construct the matrix
     boost::numeric::ublas::c_matrix<double, 2, 2> transformMatrix;
-    transformMatrix(0, 0) = a.to_number();
-    transformMatrix(0, 1) = b.to_number();
-    transformMatrix(1, 0) = c.to_number();
-    transformMatrix(1, 1) = d.to_number();
+    transformMatrix(0, 0) = toNumber(a, vm);
+    transformMatrix(0, 1) = toNumber(b, vm);
+    transformMatrix(1, 0) = toNumber(c, vm);
+    transformMatrix(1, 1) = toNumber(d, vm);
 
     // Construct the point
     PointType point;
-    point(0) = x.to_number();
-    point(1) = y.to_number();
-
-#ifdef GNASH_DEBUG_GEOM_MATRIX
-    log_debug("(Matrix.{delta}TransformPoint) This matrix: %s", 
transformMatrix);
-    log_debug("(Matrix.{delta}TransformPoint) Point vector (pre-transform): 
%s", point);
-#endif
+    point(0) = toNumber(x, vm);
+    point(1) = toNumber(y, vm);
 
     // Transform
     point = boost::numeric::ublas::prod(point, transformMatrix);
 
-#ifdef GNASH_DEBUG_GEOM_MATRIX
-    log_debug("(Matrix.{delta}TransformPoint) Point vector (post-transform): 
%s", point);
-#endif
-
     return point;
 
 }
 
 // A helper function to create a boost matrix from a Matrix object
-void fillMatrix(MatrixType& matrix,
-                         as_object& matrixObject)
+void
+fillMatrix(MatrixType& matrix, as_object& matrixObject)
 {
 
     const double u = 0.0;
@@ -850,12 +842,14 @@ void fillMatrix(MatrixType& matrix,
     matrixObject.get_member(NSV::PROP_TX, &tx);
     matrixObject.get_member(NSV::PROP_TY, &ty);
 
-    matrix(0, 0) = a.to_number();
-    matrix(0, 1) = c.to_number();
-    matrix(0, 2) = tx.to_number();
-    matrix(1, 0) = b.to_number();
-    matrix(1, 1) = d.to_number();
-    matrix(1, 2) = ty.to_number();
+    VM& vm = getVM(matrixObject);
+
+    matrix(0, 0) = toNumber(a, vm);
+    matrix(0, 1) = toNumber(c, vm);
+    matrix(0, 2) = toNumber(tx, vm);
+    matrix(1, 0) = toNumber(b, vm);
+    matrix(1, 1) = toNumber(d, vm);
+    matrix(1, 2) = toNumber(ty, vm);
     matrix(2, 0) = u;
     matrix(2, 1) = v;
     matrix(2, 2) = w;
diff --git a/libcore/asobj/flash/geom/Point_as.cpp 
b/libcore/asobj/flash/geom/Point_as.cpp
index fb053e8..aa9a2ac 100644
--- a/libcore/asobj/flash/geom/Point_as.cpp
+++ b/libcore/asobj/flash/geom/Point_as.cpp
@@ -252,15 +252,15 @@ point_normalize(const fn_call& fn)
 
     // newlen may be NaN, and we'd still be updating x/y
     // see actionscript.all/Point.as
-    double newlen = argval.to_number();
+    double newlen = toNumber(argval, getVM(fn));
 
     as_value xval, yval;
     ptr->get_member(NSV::PROP_X, &xval);
     ptr->get_member(NSV::PROP_Y, &yval);
 
-    double x = xval.to_number();
+    double x = toNumber(xval, getVM(fn));
     if (!isFinite(x)) return as_value();
-    double y = yval.to_number();
+    double y = toNumber(yval, getVM(fn));
     if (!isFinite(y)) return as_value();
 
     if ( x == 0 && y == 0 ) return as_value();
@@ -269,8 +269,8 @@ point_normalize(const fn_call& fn)
     double fact = newlen/curlen;
 
 
-    xval.set_double( xval.to_number() * fact );
-    yval.set_double( yval.to_number() * fact );
+    xval.set_double( toNumber(xval, getVM(fn)) * fact );
+    yval.set_double( toNumber(yval, getVM(fn)) * fact );
     ptr->set_member(NSV::PROP_X, xval);
     ptr->set_member(NSV::PROP_Y, yval);
 
@@ -359,8 +359,8 @@ point_subtract(const fn_call& fn)
         }
     }
 
-    x.set_double(x.to_number() - x1.to_number());
-    y.set_double(y.to_number() - y1.to_number());
+    x.set_double(toNumber(x, getVM(fn)) - toNumber(x1, getVM(fn)));
+    y.set_double(toNumber(y, getVM(fn)) - toNumber(y1, getVM(fn)));
 
     return constructPoint(fn, x, y);
 }
@@ -395,8 +395,8 @@ point_length(const fn_call& fn)
         as_value xval, yval;
         ptr->get_member(NSV::PROP_X, &xval);
         ptr->get_member(NSV::PROP_Y, &yval);
-        double x = xval.to_number();
-        double y = yval.to_number();
+        double x = toNumber(xval, getVM(fn));
+        double y = toNumber(yval, getVM(fn));
 
         double l = std::sqrt(x*x+y*y);
         return as_value(l);
@@ -458,22 +458,22 @@ point_distance(const fn_call& fn)
 
     as_value x1val;
     o1->get_member(NSV::PROP_X, &x1val);
-    double x1 = x1val.to_number();
+    double x1 = toNumber(x1val, getVM(fn));
     //if ( ! isFinite(x1) ) return as_value(NaN);
 
     as_value y1val;
     o1->get_member(NSV::PROP_Y, &y1val);
-    double y1 = y1val.to_number();
+    double y1 = toNumber(y1val, getVM(fn));
     //if ( ! isFinite(y1) ) return as_value(NaN);
 
     as_value x2val;
     o2->get_member(NSV::PROP_X, &x2val);
-    double x2 = x2val.to_number();
+    double x2 = toNumber(x2val, getVM(fn));
     //if ( ! isFinite(x2) ) return as_value(NaN);
 
     as_value y2val;
     o2->get_member(NSV::PROP_Y, &y2val);
-    double y2 = y2val.to_number();
+    double y2 = toNumber(y2val, getVM(fn));
     //if ( ! utility::isFinite(y2) ) return as_value(NaN);
 
     double hside = x2 - x1; // p1.x - p0.x;
@@ -545,11 +545,11 @@ point_interpolate(const fn_call& fn)
     }
 
 
-    double x0 = x0val.to_number();
-    double y0 = y0val.to_number();
-    double x1 = x1val.to_number();
-    double y1 = y1val.to_number();
-    double mu = muval.to_number();
+    double x0 = toNumber(x0val, getVM(fn));
+    double y0 = toNumber(y0val, getVM(fn));
+    double x1 = toNumber(x1val, getVM(fn));
+    double y1 = toNumber(y1val, getVM(fn));
+    double mu = toNumber(muval, getVM(fn));
 
     as_value xoff = mu * (x0 - x1);
     as_value yoff = mu * (y0 - y1);
@@ -591,8 +591,8 @@ point_polar(const fn_call& fn)
         );
     }
     
-    double len = lval.to_number();
-    double angle = aval.to_number();
+    double len = toNumber(lval, getVM(fn));
+    double angle = toNumber(aval, getVM(fn));
 
     double x = len * std::cos(angle);
     double y = len * std::sin(angle);

http://git.savannah.gnu.org/cgit//commit/?id=5192164c0260ca1a8ca7986274470e1bb3c9e46c


commit 5192164c0260ca1a8ca7986274470e1bb3c9e46c
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Oct 8 07:59:25 2010 +0200

    More toNumber.

diff --git a/libcore/DisplayObject.cpp b/libcore/DisplayObject.cpp
index 26b4e63..cf7c3db 100644
--- a/libcore/DisplayObject.cpp
+++ b/libcore/DisplayObject.cpp
@@ -285,7 +285,7 @@ DisplayObject::blendMode(const fn_call& fn)
 
     // Numeric argument.
     if (bm.is_number()) {
-        double mode = bm.to_number();
+        double mode = toNumber(bm, getVM(fn));
 
         // Hardlight is the last known value. This also performs range checking
         // for float-to-int conversion.
@@ -363,7 +363,7 @@ getHeight(DisplayObject& o)
 void
 setHeight(DisplayObject& o, const as_value& val)
 {
-    const double newheight = pixelsToTwips(val.to_number());
+    const double newheight = pixelsToTwips(toNumber(val, 
getVM(*getObject(&o))));
     if (newheight <= 0) {
         IF_VERBOSE_ASCODING_ERRORS(
         log_aserror(_("Setting _height=%g of DisplayObject %s (%s)"),
@@ -1089,7 +1089,7 @@ setHighQuality(DisplayObject& o, const as_value& val)
 {
     movie_root& mr = getRoot(*getObject(&o));
 
-    const double q = val.to_number();
+    const double q = toNumber(val, getVM(*getObject(&o)));
 
     if (q < 0) mr.setQuality(QUALITY_HIGH);
     else if (q > 2) mr.setQuality(QUALITY_BEST);
@@ -1115,7 +1115,7 @@ void
 setY(DisplayObject& o, const as_value& val)
 {
 
-    const double newy = val.to_number();
+    const double newy = toNumber(val, getVM(*getObject(&o)));
 
     // NaN is skipped, Infinite isn't
     if (isNaN(newy))
@@ -1146,7 +1146,7 @@ void
 setX(DisplayObject& o, const as_value& val)
 {
 
-    const double newx = val.to_number();
+    const double newx = toNumber(val, getVM(*getObject(&o)));
 
     // NaN is skipped, Infinite isn't
     if (isNaN(newx))
@@ -1177,7 +1177,7 @@ void
 setScaleX(DisplayObject& o, const as_value& val)
 {
 
-    const double scale_percent = val.to_number();
+    const double scale_percent = toNumber(val, getVM(*getObject(&o)));
 
     // NaN is skipped, Infinite is not, see actionscript.all/setProperty.as
     if (isNaN(scale_percent)) {
@@ -1204,7 +1204,7 @@ void
 setScaleY(DisplayObject& o, const as_value& val)
 {
 
-    const double scale_percent = val.to_number();
+    const double scale_percent = toNumber(val, getVM(*getObject(&o)));
 
     // NaN is skipped, Infinite is not, see actionscript.all/setProperty.as
     if (isNaN(scale_percent)) {
@@ -1241,7 +1241,7 @@ setVisible(DisplayObject& o, const as_value& val)
     /// cast to bool, as string "0" should be converted to
     /// its numeric equivalent, not interpreted as 'true', which
     /// SWF7+ does for strings.
-    const double d = val.to_number();
+    const double d = toNumber(val, getVM(*getObject(&o)));
 
     // Infinite or NaN is skipped
     if (isInf(d) || isNaN(d)) {
@@ -1271,7 +1271,7 @@ setAlpha(DisplayObject& o, const as_value& val)
     // The new internal alpha value is input / 100.0 * 256.
     // We test for finiteness later, but the multiplication
     // won't make any difference.
-    const double newAlpha = val.to_number() * 2.56;
+    const double newAlpha = toNumber(val, getVM(*getObject(&o))) * 2.56;
 
     // NaN is skipped, Infinite is not, see actionscript.all/setProperty.as
     if (isNaN(newAlpha)) {
@@ -1338,7 +1338,7 @@ setRotation(DisplayObject& o, const as_value& val)
 {
 
     // input is in degrees
-    const double rotation_val = val.to_number();
+    const double rotation_val = toNumber(val, getVM(*getObject(&o)));
 
     // NaN is skipped, Infinity isn't
     if (isNaN(rotation_val)) {
@@ -1406,7 +1406,7 @@ getWidth(DisplayObject& o)
 void
 setWidth(DisplayObject& o, const as_value& val)
 {
-    const double newwidth = pixelsToTwips(val.to_number());
+    const double newwidth = pixelsToTwips(toNumber(val, 
getVM(*getObject(&o))));
     if (newwidth <= 0) {
         IF_VERBOSE_ASCODING_ERRORS(
         log_aserror(_("Setting _width=%g of DisplayObject %s (%s)"),
diff --git a/libcore/asobj/MovieClip_as.cpp b/libcore/asobj/MovieClip_as.cpp
index 68a84bf..f0b9411 100644
--- a/libcore/asobj/MovieClip_as.cpp
+++ b/libcore/asobj/MovieClip_as.cpp
@@ -1300,7 +1300,7 @@ movieclip_globalToLocal(const fn_call& fn)
         );
         return ret;
     }
-    x = pixelsToTwips(tmp.to_number());
+    x = pixelsToTwips(toNumber(tmp, getVM(fn)));
 
     if ( ! obj->get_member(NSV::PROP_Y, &tmp) )
     {
@@ -1311,7 +1311,7 @@ movieclip_globalToLocal(const fn_call& fn)
         );
         return ret;
     }
-    y = pixelsToTwips(tmp.to_number());
+    y = pixelsToTwips(toNumber(tmp, getVM(fn)));
 
     point    pt(x, y);
     const SWFMatrix world_mat = getWorldMatrix(*movieclip).invert();
@@ -1362,7 +1362,7 @@ movieclip_localToGlobal(const fn_call& fn)
         );
         return ret;
     }
-    x = pixelsToTwips(tmp.to_number());
+    x = pixelsToTwips(toNumber(tmp, getVM(fn)));
 
     if ( ! obj->get_member(NSV::PROP_Y, &tmp) )
     {
@@ -1373,7 +1373,7 @@ movieclip_localToGlobal(const fn_call& fn)
         );
         return ret;
     }
-    y = pixelsToTwips(tmp.to_number());
+    y = pixelsToTwips(toNumber(tmp, getVM(fn)));
 
     point pt(x, y);
     const SWFMatrix world_mat = getWorldMatrix(*movieclip);
@@ -1816,7 +1816,7 @@ movieclip_beginGradientFill(const fn_call& fn)
         /// Alpha is the range 0..100.
         as_value alpVal = getMember(*alphas, key);
         const double a = alpVal.is_number() ?
-            clamp<double>(alpVal.to_number(), 0, 100) : 0;
+            clamp<double>(toNumber(alpVal, getVM(fn)), 0, 100) : 0;
         const boost::uint8_t alp = 0xff * (a / 100);
 
         // Ratio is the range 0..255, but a ratio may never be smaller than
diff --git a/libcore/asobj/TextFormat_as.cpp b/libcore/asobj/TextFormat_as.cpp
index 4c8f49b..e18fa16 100644
--- a/libcore/asobj/TextFormat_as.cpp
+++ b/libcore/asobj/TextFormat_as.cpp
@@ -73,7 +73,7 @@ PixelsToTwips : SetBase
 {
     PixelsToTwips(const fn_call& fn) : SetBase(fn) {}
     boost::int32_t operator()(const as_value& val) const {
-        return pixelsToTwips(val.to_number());
+        return pixelsToTwips(toNumber(val, getVM(fn())));
     }
 };
 
@@ -182,12 +182,13 @@ class
 PushToVector
 {
 public:
-    PushToVector(std::vector<int>& v) : _v(v) {}
+    PushToVector(std::vector<int>& v, const fn_call& fn) : _v(v), _fn(fn) {}
     void operator()(const as_value& val) {
-        _v.push_back(val.to_number());
+        _v.push_back(toNumber(val, getVM(_fn)));
     }
 private:
     std::vector<int>& _v;
+    const fn_call& _fn;
 };
 
 
@@ -492,7 +493,7 @@ textformat_tabStops(const fn_call& fn)
 
        std::vector<int> tabStops;
 
-    PushToVector pv(tabStops);
+    PushToVector pv(tabStops, fn);
     foreachArray(*arg, pv);
 
     relay->tabStopsSet(tabStops);
@@ -574,7 +575,8 @@ textformat_getTextExtent(const fn_call& fn)
     const bool limitWidth = (fn.nargs > 1);
     
     // Everything must be in twips here.
-    const double tfw = limitWidth ? pixelsToTwips(toNumber(fn.arg(1), 
getVM(fn))) : 0;
+    const double tfw = limitWidth ?
+        pixelsToTwips(toNumber(fn.arg(1), getVM(fn))) : 0;
 
     const bool bold = relay->bold() ? *relay->bold() : false;
     const bool italic = relay->italic() ? *relay->italic() : false;

http://git.savannah.gnu.org/cgit//commit/?id=76f94f4f0e97b4d5ab9fabfa98e22c562f0a8bed


commit 76f94f4f0e97b4d5ab9fabfa98e22c562f0a8bed
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Oct 7 18:40:55 2010 +0200

    Use toNumber more.

diff --git a/extensions/fileio/fileio.cpp b/extensions/fileio/fileio.cpp
index f38793a..2aef409 100644
--- a/extensions/fileio/fileio.cpp
+++ b/extensions/fileio/fileio.cpp
@@ -470,7 +470,7 @@ fileio_fputc(const fn_call& fn)
 //    GNASH_REPORT_FUNCTION;
     FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
     assert(ptr);    
-    int c = (int) fn.arg(0).to_number();
+    int c = (int) toNumber(fn.arg(0), getVM(fn));
     return as_value(ptr->fputc(c));
 }
 
@@ -518,7 +518,7 @@ fileio_fseek(const fn_call& fn)
 //    GNASH_REPORT_FUNCTION;
     FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
     assert(ptr);    
-    long c = static_cast<long>(fn.arg(0).to_number());
+    long c = static_cast<long>(toNumber(fn.arg(0), getVM(fn)));
     return as_value(ptr->fseek(c));
 }
 
diff --git a/libcore/asobj/Array_as.cpp b/libcore/asobj/Array_as.cpp
index d0aa32c..2d309f2 100644
--- a/libcore/asobj/Array_as.cpp
+++ b/libcore/asobj/Array_as.cpp
@@ -1019,7 +1019,7 @@ array_sort(const fn_call& fn)
     boost::uint8_t flags = 0;
 
     if (fn.nargs == 1 && fn.arg(0).is_number()) {
-        flags = static_cast<boost::uint8_t>(fn.arg(0).to_number());
+        flags = static_cast<boost::uint8_t>(toNumber(fn.arg(0), getVM(fn)));
     }
     else if (fn.arg(0).is_function()) {
         // Get comparison function
@@ -1030,7 +1030,7 @@ array_sort(const fn_call& fn)
         bool (*icmp)(int);
     
         if (fn.nargs == 2 && fn.arg(1).is_number()) {
-            flags=static_cast<boost::uint8_t>(fn.arg(1).to_number());
+            flags=static_cast<boost::uint8_t>(toNumber(fn.arg(1), getVM(fn)));
         }
 
         if (flags & SORT_DESCENDING) icmp = &int_lt_or_eq;
@@ -1092,7 +1092,7 @@ array_sortOn(const fn_call& fn)
             st.find(fn.arg(0).to_string(version));
 
         if (fn.nargs > 1 && fn.arg(1).is_number()) {
-            flags = static_cast<boost::uint8_t>(fn.arg(1).to_number());
+            flags = static_cast<boost::uint8_t>(toNumber(fn.arg(1), 
getVM(fn)));
             flags = flag_preprocess(flags, &do_unique, &do_index);
         }
 
diff --git a/libcore/asobj/Camera_as.cpp b/libcore/asobj/Camera_as.cpp
index fad8c4e..37dc9d5 100644
--- a/libcore/asobj/Camera_as.cpp
+++ b/libcore/asobj/Camera_as.cpp
@@ -296,9 +296,9 @@ camera_setmode(const fn_call& fn)
 
     const size_t nargs = fn.nargs;
 
-    const double width = nargs ? fn.arg(0).to_number() : 160;
-    const double height = nargs > 1 ? fn.arg(1).to_number() : 120;
-    const double fps = nargs >  2? fn.arg(2).to_number() : 15;
+    const double width = nargs ? toNumber(fn.arg(0), getVM(fn)) : 160;
+    const double height = nargs > 1 ? toNumber(fn.arg(1), getVM(fn)) : 120;
+    const double fps = nargs >  2? toNumber(fn.arg(2), getVM(fn)) : 15;
     const bool favorArea = nargs > 3 ? toBool(fn.arg(3), getVM(fn)) : true;
 
     // TODO: handle overflow
@@ -318,8 +318,8 @@ camera_setmotionlevel(const fn_call& fn)
     
     const size_t nargs = fn.nargs;
 
-    const double ml = nargs > 0 ? fn.arg(0).to_number() : 50;
-    const double mt = nargs > 1 ? fn.arg(1).to_number() : 2000;
+    const double ml = nargs > 0 ? toNumber(fn.arg(0), getVM(fn)) : 50;
+    const double mt = nargs > 1 ? toNumber(fn.arg(1), getVM(fn)) : 2000;
 
     const size_t motionLevel = (ml >= 0 && ml <= 100) ? ml : 100;
 
@@ -337,8 +337,8 @@ camera_setquality(const fn_call& fn)
 
     const size_t nargs = fn.nargs;
 
-    const double b = nargs > 0 ? fn.arg(0).to_number() : 16384;
-    const double q = nargs > 1 ? fn.arg(1).to_number() : 0;
+    const double b = nargs > 0 ? toNumber(fn.arg(0), getVM(fn)) : 16384;
+    const double q = nargs > 1 ? toNumber(fn.arg(1), getVM(fn)) : 0;
 
     size_t quality = (q < 0 || q > 100) ? 100 : q;
 
diff --git a/libcore/asobj/Date_as.cpp b/libcore/asobj/Date_as.cpp
index aca26a4..c37232e 100644
--- a/libcore/asobj/Date_as.cpp
+++ b/libcore/asobj/Date_as.cpp
@@ -435,7 +435,7 @@ date_new(const fn_call& fn)
     }
     else if (fn.nargs == 1) {
         // Set the value in milliseconds since 1970 UTC
-        obj->setRelay(new Date_as(fn.arg(0).to_number()));
+        obj->setRelay(new Date_as(toNumber(fn.arg(0), getVM(fn))));
     }
     else {
         // Create a time from the supplied (at least 2) arguments.
@@ -729,7 +729,7 @@ date_setTime(const fn_call& fn)
     else {
         // returns a double
         const double magicMaxValue = 8.64e+15;
-        double d = fn.arg(0).to_number();
+        double d = toNumber(fn.arg(0), getVM(fn));
 
         if (!isFinite(d) || std::abs(d) > magicMaxValue) {
             date->setTimeValue(NaN);
@@ -887,7 +887,7 @@ date_setYear(const fn_call& fn)
 
         // TODO: Should truncation be done before or after subtracting 1900?
         
-        double year = fn.arg(0).to_number();
+        double year = toNumber(fn.arg(0), getVM(fn));
         if (year < 0 || year > 100) year -= 1900;
 
         truncateDouble(gt.year, year);
@@ -943,13 +943,13 @@ date_setmonth(const fn_call& fn)
 
         // It seems odd, but FlashPlayer takes all bad month values to mean
         // January
-        double monthvalue =  fn.arg(0).to_number();
+        double monthvalue =  toNumber(fn.arg(0), getVM(fn));
         if (isNaN(monthvalue) || isInf(monthvalue)) monthvalue = 0.0;
         truncateDouble(gt.month, monthvalue);
 
         // If the day-of-month value is invalid instead, the result is NaN.
         if (fn.nargs >= 2) {
-            double mdayvalue = fn.arg(1).to_number();
+            double mdayvalue = toNumber(fn.arg(1), getVM(fn));
             if (isNaN(mdayvalue) || isInf(mdayvalue)) {
                 date->setTimeValue(NaN);
                 return as_value(date->getTimeValue());
@@ -1160,7 +1160,7 @@ date_setMilliseconds(const fn_call& fn)
         GnashTime gt;
 
         dateToGnashTime(*date, gt, utc);
-        truncateDouble(gt.millisecond, fn.arg(0).to_number());
+        truncateDouble(gt.millisecond, toNumber(fn.arg(0), getVM(fn)));
 
         if (fn.nargs > 1) {
             IF_VERBOSE_ASCODING_ERRORS(
@@ -1267,7 +1267,7 @@ date_UTC(const fn_call& fn) {
             gt.month = toInt(fn.arg(1));
             {
                 boost::int32_t year = 0;
-                truncateDouble(year, fn.arg(0).to_number());
+                truncateDouble(year, toNumber(fn.arg(0), getVM(fn)));
                 if (year < 100) gt.year = year;
                 else gt.year = year - 1900;
             }
@@ -1296,7 +1296,7 @@ rogue_date_args(const fn_call& fn, unsigned maxargs)
     if (fn.nargs < maxargs) maxargs = fn.nargs;
 
     for (unsigned int i = 0; i < maxargs; i++) {
-        double arg = fn.arg(i).to_number();
+        double arg = toNumber(fn.arg(i), getVM(fn));
 
         if (isNaN(arg)) return(NaN);
 
diff --git a/libcore/asobj/Global_as.cpp b/libcore/asobj/Global_as.cpp
index b1a2119..ee845c7 100644
--- a/libcore/asobj/Global_as.cpp
+++ b/libcore/asobj/Global_as.cpp
@@ -456,7 +456,7 @@ global_isNaN(const fn_call& fn)
 {
     ASSERT_FN_ARGS_IS_1
 
-    return as_value(static_cast<bool>(isNaN(fn.arg(0).to_number())));
+    return as_value(static_cast<bool>(isNaN(toNumber(fn.arg(0), getVM(fn)))));
 }
 
 
@@ -465,7 +465,7 @@ global_isfinite(const fn_call& fn)
 {
     ASSERT_FN_ARGS_IS_1
 
-    return as_value(static_cast<bool>(isFinite(fn.arg(0).to_number())));
+    return as_value(static_cast<bool>(isFinite(toNumber(fn.arg(0), 
getVM(fn)))));
 }
 
 /// \brief Encode a string to URL-encoded format
@@ -683,7 +683,7 @@ global_assetpropflags(const fn_call& fn)
     // are used to determine whether the list of child names should be hidden,
     // un-hidden, protected from over-write, un-protected from over-write,
     // protected from deletion and un-protected from deletion
-    const int setTrue = int(fn.arg(2).to_number()) & flagsMask;
+    const int setTrue = int(toNumber(fn.arg(2), getVM(fn))) & flagsMask;
 
     // Is another integer bitmask that works like set_true,
     // except it sets the attributes to false. The
@@ -1053,7 +1053,7 @@ global_setInterval(const fn_call& fn)
 
        // Get interval time
        unsigned long ms =
-        static_cast<unsigned long>(fn.arg(timer_arg).to_number());
+        static_cast<unsigned long>(toNumber(fn.arg(timer_arg), getVM(fn)));
        // TODO: check validity of interval time number ?
 
        // Parse arguments 
@@ -1123,7 +1123,7 @@ global_setTimeout(const fn_call& fn)
 
        // Get interval time
        unsigned long ms =
-        static_cast<unsigned long>(fn.arg(timer_arg).to_number());
+        static_cast<unsigned long>(toNumber(fn.arg(timer_arg), getVM(fn)));
 
        // Parse arguments 
     fn_call::Args args;
@@ -1155,7 +1155,7 @@ global_clearInterval(const fn_call& fn)
         return as_value();
     }
 
-       int id = int(fn.arg(0).to_number());
+       int id = int(toNumber(fn.arg(0), getVM(fn)));
 
        movie_root& root = getRoot(fn);
        bool ret = root.clear_interval_timer(id);
diff --git a/libcore/asobj/Math_as.cpp b/libcore/asobj/Math_as.cpp
index b9239bf..ef2ad3d 100644
--- a/libcore/asobj/Math_as.cpp
+++ b/libcore/asobj/Math_as.cpp
@@ -106,8 +106,8 @@ as_value
 unaryFunction(const fn_call& fn)
 {
     if (fn.nargs < 1) return as_value(NaN);
-    double arg = fn.arg(0).to_number();        
-    if (fn.nargs > 1) fn.arg(1).to_number();
+    double arg = toNumber(fn.arg(0), getVM(fn));       
+    if (fn.nargs > 1) toNumber(fn.arg(1), getVM(fn));
     return as_value(Func(arg));
 }
 
@@ -124,8 +124,8 @@ as_value
 binaryFunction(const fn_call& fn)
 {
     if (fn.nargs < 2) return as_value(NaN);
-    double arg0 = fn.arg(0).to_number();       
-    double arg1 = fn.arg(1).to_number();
+    double arg0 = toNumber(fn.arg(0), getVM(fn));      
+    double arg1 = toNumber(fn.arg(1), getVM(fn));
     return as_value(Func(arg0, arg1));
 }
 
@@ -139,14 +139,14 @@ binaryFunction<std::pow>(const fn_call& fn)
 {
     if (!fn.nargs) return as_value(NaN);
     
-    double arg0 = fn.arg(0).to_number();
+    double arg0 = toNumber(fn.arg(0), getVM(fn));
 
     if (fn.nargs < 2) {
         if (arg0 == 1) return as_value(1);
         return as_value(NaN);
     }
 
-    double arg1 = fn.arg(1).to_number();
+    double arg1 = toNumber(fn.arg(1), getVM(fn));
     return as_value(isFinite(arg0) ? std::pow(arg0, arg1) : NaN );
 }
 
@@ -160,8 +160,8 @@ math_min(const fn_call& fn)
 
        if (fn.nargs < 2) return as_value(NaN);
 
-       double arg0 = fn.arg(0).to_number();
-       double arg1 = fn.arg(1).to_number();
+       double arg0 = toNumber(fn.arg(0), getVM(fn));
+       double arg1 = toNumber(fn.arg(1), getVM(fn));
 
        if (isNaN(arg0) || isNaN(arg1))
        {
@@ -182,8 +182,8 @@ math_max(const fn_call& fn)
        
     if (fn.nargs < 2) return as_value(NaN);
 
-       double arg0 = fn.arg(0).to_number();
-       double arg1 = fn.arg(1).to_number();
+       double arg0 = toNumber(fn.arg(0), getVM(fn));
+       double arg1 = toNumber(fn.arg(1), getVM(fn));
 
        if (isNaN(arg0) || isNaN(arg1))
        {
@@ -201,8 +201,8 @@ as_value
 math_random(const fn_call& fn)
 {
 
-    if (fn.nargs) fn.arg(0).to_number();
-    if (fn.nargs > 1) fn.arg(1).to_number();
+    if (fn.nargs) toNumber(fn.arg(0), getVM(fn));
+    if (fn.nargs > 1) toNumber(fn.arg(1), getVM(fn));
 
        VM::RNG& rnd = getVM(fn).randomNumberGenerator();
 
diff --git a/libcore/asobj/Microphone_as.cpp b/libcore/asobj/Microphone_as.cpp
index 2914079..0c0ff2c 100644
--- a/libcore/asobj/Microphone_as.cpp
+++ b/libcore/asobj/Microphone_as.cpp
@@ -446,7 +446,7 @@ microphone_setsilencelevel(const fn_call& fn)
         return as_value();
     }
 
-    const double level = clamp<double>(fn.arg(0).to_number(), 0, 100);
+    const double level = clamp<double>(toNumber(fn.arg(0), getVM(fn)), 0, 100);
     ptr->setSilenceLevel(level);
     
     if (numargs > 1) {
diff --git a/libcore/asobj/MovieClip_as.cpp b/libcore/asobj/MovieClip_as.cpp
index 7f2d705..68a84bf 100644
--- a/libcore/asobj/MovieClip_as.cpp
+++ b/libcore/asobj/MovieClip_as.cpp
@@ -461,7 +461,7 @@ movieclip_attachMovie(const fn_call& fn)
     // kirupa (http://www.kirupa.com/developer/actionscript/depths2.htm)
     // Tests in misc-ming.all/DepthLimitsTest.c show that 2130690044 is the
     // maximum valid depth.
-    const double depth = fn.arg(2).to_number();
+    const double depth = toNumber(fn.arg(2), getVM(fn));
     
     // This also checks for overflow, as both numbers are expressible as
     // boost::int32_t.
@@ -650,7 +650,7 @@ movieclip_swapDepths(const fn_call& fn)
     // movieclip.swapDepth(depth)
     else {
         
-        const double td = fn.arg(0).to_number();
+        const double td = toNumber(fn.arg(0), getVM(fn));
         if (isNaN(td)) {
             IF_VERBOSE_ASCODING_ERRORS(
                 std::stringstream ss; fn.dump_args(ss);
@@ -721,7 +721,7 @@ movieclip_duplicateMovieClip(const fn_call& fn)
     const std::string& newname = fn.arg(0).to_string();
 
     // Depth as in attachMovie
-    const double depth = fn.arg(1).to_number();
+    const double depth = toNumber(fn.arg(1), getVM(fn));
     
     // This also checks for overflow, as both numbers are expressible as
     // boost::int32_t.
@@ -1011,8 +1011,8 @@ movieclip_hitTest(const fn_call& fn)
 
         case 2: // x, y
         {
-            boost::int32_t x = pixelsToTwips(fn.arg(0).to_number());
-            boost::int32_t y = pixelsToTwips(fn.arg(1).to_number());
+            boost::int32_t x = pixelsToTwips(toNumber(fn.arg(0), getVM(fn)));
+            boost::int32_t y = pixelsToTwips(toNumber(fn.arg(1), getVM(fn)));
 
             return movieclip->pointInBounds(x, y);
         }
@@ -1450,8 +1450,8 @@ movieclip_lineTo(const fn_call& fn)
         return as_value();
     }
 
-    double x = fn.arg(0).to_number();
-    double y = fn.arg(1).to_number();
+    double x = toNumber(fn.arg(0), getVM(fn));
+    double y = toNumber(fn.arg(1), getVM(fn));
         
     if (!isFinite(x)) x = 0;
     if (!isFinite(y)) y = 0;
@@ -1476,8 +1476,8 @@ movieclip_moveTo(const fn_call& fn)
         return as_value();
     }
 
-    double x = fn.arg(0).to_number();
-    double y = fn.arg(1).to_number();
+    double x = toNumber(fn.arg(0), getVM(fn));
+    double y = toNumber(fn.arg(1), getVM(fn));
      
     if (!isFinite(x)) x = 0;
     if (!isFinite(y)) y = 0;
@@ -1595,7 +1595,7 @@ movieclip_lineStyle(const fn_call& fn)
             pixelHinting = toBool(fn.arg(3), getVM(fn));
         case 3:
         {
-            const float alphaval = clamp<float>(fn.arg(2).to_number(),
+            const float alphaval = clamp<float>(toNumber(fn.arg(2), getVM(fn)),
                                      0, 100);
             a = boost::uint8_t(255 * (alphaval / 100));
         }
@@ -1611,7 +1611,7 @@ movieclip_lineStyle(const fn_call& fn)
         }
         case 1:
             thickness = boost::uint16_t(pixelsToTwips(clamp<float>(
-                            fn.arg(0).to_number(), 0, 255)));
+                            toNumber(fn.arg(0), getVM(fn)), 0, 255)));
             break;
     }
 
@@ -1636,10 +1636,10 @@ movieclip_curveTo(const fn_call& fn)
         return as_value();
     }
 
-    double cx = fn.arg(0).to_number();
-    double cy = fn.arg(1).to_number();
-    double ax = fn.arg(2).to_number();
-    double ay = fn.arg(3).to_number();
+    double cx = toNumber(fn.arg(0), getVM(fn));
+    double cy = toNumber(fn.arg(1), getVM(fn));
+    double ax = toNumber(fn.arg(2), getVM(fn));
+    double ay = toNumber(fn.arg(3), getVM(fn));
 
     if (!isFinite(cx)) cx = 0;
     if (!isFinite(cy)) cy = 0;
@@ -1679,7 +1679,7 @@ movieclip_beginFill(const fn_call& fn)
 
     // 2^24 is the max here
     const boost::uint32_t rgbval =
-        clamp<float>(fn.arg(0).to_number(), 0, 16777216);
+        clamp<float>(toNumber(fn.arg(0), getVM(fn)), 0, 16777216);
 
     const boost::uint8_t r = (rgbval & 0xFF0000) >> 16;
     const boost::uint8_t g = (rgbval & 0x00FF00) >> 8;
@@ -1871,7 +1871,7 @@ movieclip_beginGradientFill(const fn_call& fn)
 
     /// Add a focus if present.
     if (fn.nargs > 7) {
-        fd.setFocalPoint(fn.arg(7).to_number());
+        fd.setFocalPoint(toNumber(fn.arg(7), getVM(fn)));
     }
 
     movieclip->graphics().beginFill(fd);
@@ -1898,10 +1898,10 @@ movieclip_startDrag(const fn_call& fn)
 
         if ( fn.nargs >= 5)
         {
-            double x0 = fn.arg(1).to_number();
-            double y0 = fn.arg(2).to_number();
-            double x1 = fn.arg(3).to_number();
-            double y1 = fn.arg(4).to_number();
+            double x0 = toNumber(fn.arg(1), getVM(fn));
+            double y0 = toNumber(fn.arg(2), getVM(fn));
+            double x1 = toNumber(fn.arg(3), getVM(fn));
+            double y1 = toNumber(fn.arg(4), getVM(fn));
 
             // check for infinite values
             bool gotinf = false;
diff --git a/libcore/asobj/NetStream_as.cpp b/libcore/asobj/NetStream_as.cpp
index b4ea388..11d4d74 100644
--- a/libcore/asobj/NetStream_as.cpp
+++ b/libcore/asobj/NetStream_as.cpp
@@ -1698,7 +1698,7 @@ netstream_seek(const fn_call& fn)
     boost::uint32_t time = 0;
     if (fn.nargs > 0)
     {
-        time = static_cast<boost::uint32_t>(fn.arg(0).to_number());
+        time = static_cast<boost::uint32_t>(toNumber(fn.arg(0), getVM(fn)));
     }
     ns->seek(time);
 
@@ -1718,7 +1718,7 @@ netstream_setbuffertime(const fn_call& fn)
     double time = 0;
     if (fn.nargs > 0)
     {
-        time = fn.arg(0).to_number();
+        time = toNumber(fn.arg(0), getVM(fn));
     }
 
     // TODO: don't allow a limit < 100 
diff --git a/libcore/asobj/Number_as.cpp b/libcore/asobj/Number_as.cpp
index fc17a5b..d95edbb 100644
--- a/libcore/asobj/Number_as.cpp
+++ b/libcore/asobj/Number_as.cpp
@@ -102,7 +102,7 @@ number_ctor(const fn_call& fn)
 {
     double val = 0;
     if (fn.nargs > 0) {
-        val = fn.arg(0).to_number();
+        val = toNumber(fn.arg(0), getVM(fn));
     }
 
     if (!fn.isInstantiation()) {
diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index 10e4cdb..6b4f690 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -949,10 +949,10 @@ sound_start(const fn_call& fn)
     double secondOffset = 0;
 
     if (fn.nargs > 0) {
-        secondOffset = fn.arg(0).to_number();
+        secondOffset = toNumber(fn.arg(0), getVM(fn));
 
         if (fn.nargs > 1) {
-            loop = (int) fn.arg(1).to_number() - 1;
+            loop = (int) toNumber(fn.arg(1), getVM(fn)) - 1;
 
             // -1 means infinite playing of sound
             // sanity check
@@ -1199,7 +1199,7 @@ sound_setvolume(const fn_call& fn)
     }
 
     Sound_as* so = ensure<ThisIsNative<Sound_as> >(fn);
-    int volume = (int) fn.arg(0).to_number();
+    int volume = (int) toNumber(fn.arg(0), getVM(fn));
 
     so->setVolume(volume);
     return as_value();
diff --git a/libcore/asobj/String_as.cpp b/libcore/asobj/String_as.cpp
index 6fd5bf7..9ae1d61 100644
--- a/libcore/asobj/String_as.cpp
+++ b/libcore/asobj/String_as.cpp
@@ -578,7 +578,7 @@ string_charCodeAt(const fn_call& fn)
         }
     )
 
-    size_t index = static_cast<size_t>(fn.arg(0).to_number());
+    size_t index = static_cast<size_t>(toNumber(fn.arg(0), getVM(fn)));
 
     if (index >= wstr.length()) {
         as_value rv;
diff --git a/libcore/asobj/TextField_as.cpp b/libcore/asobj/TextField_as.cpp
index 25a97de..1e11262 100644
--- a/libcore/asobj/TextField_as.cpp
+++ b/libcore/asobj/TextField_as.cpp
@@ -334,7 +334,7 @@ textfield_borderColor(const fn_call& fn)
     }
     else {
         rgba newColor;
-        newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_number()));
+        newColor.parseRGB(static_cast<boost::uint32_t>(toNumber(fn.arg(0), 
getVM(fn))));
         ptr->setBorderColor(newColor);
     }
 
@@ -354,7 +354,7 @@ textfield_textColor(const fn_call& fn)
 
     // Setter
     rgba newColor;
-    newColor.parseRGB(static_cast<boost::uint32_t>(fn.arg(0).to_number()));
+    newColor.parseRGB(static_cast<boost::uint32_t>(toNumber(fn.arg(0), 
getVM(fn))));
     ptr->setTextColor(newColor);
 
     return as_value();
@@ -797,7 +797,7 @@ textfield_bottomScroll(const fn_call& fn)
         return as_value(1 + text->getBottomScroll());
     }
     // Setter
-    //text->setBottomScroll(int(fn.arg(0).to_number())); READ-ONLY
+    //text->setBottomScroll(int(toNumber(fn.arg(0), getVM(fn)))); READ-ONLY
 
     return as_value();
 }
@@ -817,7 +817,7 @@ textfield_maxhscroll(const fn_call& fn)
         return as_value(text->getMaxHScroll());
     }
     // Setter
-    //text->setMaxHScroll(int(fn.arg(0).to_number())); READ-ONLY
+    //text->setMaxHScroll(int(toNumber(fn.arg(0), getVM(fn)))); READ-ONLY
 
     return as_value();
 }
@@ -935,7 +935,7 @@ textfield_scroll(const fn_call& fn)
         return as_value(1 + text->getScroll());
     }
     // Setter
-    text->setScroll(int(fn.arg(0).to_number()) - 1); 
+    text->setScroll(int(toNumber(fn.arg(0), getVM(fn))) - 1); 
 
     return as_value();
 }
@@ -953,7 +953,7 @@ textfield_hscroll(const fn_call& fn)
         return as_value(text->getHScroll());
     }
     // Setter
-    text->setHScroll(int(fn.arg(0).to_number()));
+    text->setHScroll(int(toNumber(fn.arg(0), getVM(fn))));
 
     return as_value();
 }
diff --git a/libcore/asobj/TextFormat_as.cpp b/libcore/asobj/TextFormat_as.cpp
index d97dd78..4c8f49b 100644
--- a/libcore/asobj/TextFormat_as.cpp
+++ b/libcore/asobj/TextFormat_as.cpp
@@ -574,7 +574,7 @@ textformat_getTextExtent(const fn_call& fn)
     const bool limitWidth = (fn.nargs > 1);
     
     // Everything must be in twips here.
-    const double tfw = limitWidth ? pixelsToTwips(fn.arg(1).to_number()) : 0;
+    const double tfw = limitWidth ? pixelsToTwips(toNumber(fn.arg(1), 
getVM(fn))) : 0;
 
     const bool bold = relay->bold() ? *relay->bold() : false;
     const bool italic = relay->italic() ? *relay->italic() : false;
diff --git a/libcore/asobj/XMLSocket_as.cpp b/libcore/asobj/XMLSocket_as.cpp
index 31d5b08..4cb39c4 100644
--- a/libcore/asobj/XMLSocket_as.cpp
+++ b/libcore/asobj/XMLSocket_as.cpp
@@ -321,7 +321,7 @@ xmlsocket_connect(const fn_call& fn)
     
     as_value hostval = fn.arg(0);
     const std::string& host = hostval.to_string();
-    const double port = fn.arg(1).to_number();
+    const double port = toNumber(fn.arg(1), getVM(fn));
     
     // Port numbers above 65535 are rejected always, but not port numbers below
     // 0. It's not clear what happens with them.
diff --git a/libcore/asobj/XML_as.cpp b/libcore/asobj/XML_as.cpp
index 6b2102f..fac45a4 100644
--- a/libcore/asobj/XML_as.cpp
+++ b/libcore/asobj/XML_as.cpp
@@ -674,7 +674,7 @@ xml_status(const fn_call& fn)
         return as_value(ptr->status());
     }
 
-    const double status = fn.arg(0).to_number();
+    const double status = toNumber(fn.arg(0), getVM(fn));
     if (isNaN(status) ||
             status > std::numeric_limits<boost::int32_t>::max() ||
             status < std::numeric_limits<boost::int32_t>::min()) {
diff --git a/libcore/asobj/flash/display/BitmapData_as.cpp 
b/libcore/asobj/flash/display/BitmapData_as.cpp
index 977fd01..18842f5 100644
--- a/libcore/asobj/flash/display/BitmapData_as.cpp
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp
@@ -684,8 +684,8 @@ bitmapdata_setPixel(const fn_call& fn)
         return as_value();
     }
 
-    const double x = fn.arg(0).to_number();
-    const double y = fn.arg(1).to_number();
+    const double x = toNumber(fn.arg(0), getVM(fn));
+    const double y = toNumber(fn.arg(1), getVM(fn));
     if (isNaN(x) || isNaN(y) || x < 0 || y < 0) return as_value();
     if (x >= ptr->width() || y >= ptr->height()) {
         return as_value();
@@ -708,8 +708,8 @@ bitmapdata_setPixel32(const fn_call& fn)
         return as_value();
     }
 
-    const double x = fn.arg(0).to_number();
-    const double y = fn.arg(1).to_number();
+    const double x = toNumber(fn.arg(0), getVM(fn));
+    const double y = toNumber(fn.arg(1), getVM(fn));
     if (isNaN(x) || isNaN(y) || x < 0 || y < 0) return as_value();
     if (x >= ptr->width() || y >= ptr->height()) {
         return as_value();
diff --git a/libcore/asobj/flash/filters/BevelFilter_as.cpp 
b/libcore/asobj/flash/filters/BevelFilter_as.cpp
index d70f680..4d8bc1b 100644
--- a/libcore/asobj/flash/filters/BevelFilter_as.cpp
+++ b/libcore/asobj/flash/filters/BevelFilter_as.cpp
@@ -100,7 +100,7 @@ bevelfilter_distance(const fn_call& fn)
         return as_value(ptr->m_distance );
     }
     
-    float sp_distance = fn.arg(0).to_number();
+    float sp_distance = toNumber(fn.arg(0), getVM(fn));
     ptr->m_distance = sp_distance;
     return as_value();
 }
@@ -112,7 +112,7 @@ bevelfilter_angle(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_angle);
     }
-    double sp_angle = fn.arg(0).to_number();
+    double sp_angle = toNumber(fn.arg(0), getVM(fn));
     ptr->m_angle = sp_angle;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/DropShadowFilter_as.cpp 
b/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
index 4c255fe..a70c11d 100644
--- a/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
+++ b/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
@@ -97,7 +97,7 @@ dropshadowfilter_distance(const fn_call& fn)
         return as_value(ptr->m_distance );
     }
     
-    float sp_distance = fn.arg(0).to_number();
+    float sp_distance = toNumber(fn.arg(0), getVM(fn));
     ptr->m_distance = sp_distance;
     return as_value();
 }
@@ -109,7 +109,7 @@ dropshadowfilter_color(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_color);
     }
-    double sp_color = fn.arg(0).to_number();
+    double sp_color = toNumber(fn.arg(0), getVM(fn));
     ptr->m_color = sp_color;
     return as_value();
 }
@@ -121,7 +121,7 @@ dropshadowfilter_alpha(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_alpha);
     }
-    double sp_alpha = fn.arg(0).to_number();
+    double sp_alpha = toNumber(fn.arg(0), getVM(fn));
     ptr->m_alpha = sp_alpha;
     return as_value();
 }
@@ -133,7 +133,7 @@ dropshadowfilter_angle(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_angle);
     }
-    double sp_angle = fn.arg(0).to_number();
+    double sp_angle = toNumber(fn.arg(0), getVM(fn));
     ptr->m_angle = sp_angle;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp 
b/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
index 5b8a3ee..e07b6ae 100644
--- a/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
+++ b/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
@@ -97,7 +97,7 @@ gradientbevelfilter_distance(const fn_call& fn)
         return as_value(ptr->m_distance );
     }
     
-    float sp_distance = fn.arg(0).to_number();
+    float sp_distance = toNumber(fn.arg(0), getVM(fn));
     ptr->m_distance = sp_distance;
     return as_value();
 }
@@ -109,7 +109,7 @@ gradientbevelfilter_angle(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_angle);
     }
-    double sp_angle = fn.arg(0).to_number();
+    double sp_angle = toNumber(fn.arg(0), getVM(fn));
     ptr->m_angle = sp_angle;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp 
b/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
index f3c4c2b..d85c2a2 100644
--- a/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
+++ b/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
@@ -97,7 +97,7 @@ gradientglowfilter_distance(const fn_call& fn)
         return as_value(ptr->m_distance );
     }
     
-    float sp_distance = fn.arg(0).to_number();
+    float sp_distance = toNumber(fn.arg(0), getVM(fn));
     ptr->m_distance = sp_distance;
     return as_value();
 }
@@ -109,7 +109,7 @@ gradientglowfilter_angle(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_angle);
     }
-    double sp_angle = fn.arg(0).to_number();
+    double sp_angle = toNumber(fn.arg(0), getVM(fn));
     ptr->m_angle = sp_angle;
     return as_value();
 }
diff --git a/libcore/asobj/flash/geom/ColorTransform_as.cpp 
b/libcore/asobj/flash/geom/ColorTransform_as.cpp
index ba820f8..2333fa0 100644
--- a/libcore/asobj/flash/geom/ColorTransform_as.cpp
+++ b/libcore/asobj/flash/geom/ColorTransform_as.cpp
@@ -158,7 +158,7 @@ colortransform_alphaMultiplier(const fn_call& fn)
         return as_value(relay->getAlphaMultiplier());
     }
     
-    relay->setAlphaMultiplier(fn.arg(0).to_number());
+    relay->setAlphaMultiplier(toNumber(fn.arg(0), getVM(fn)));
        return as_value();
 }
 
@@ -170,7 +170,7 @@ colortransform_alphaOffset(const fn_call& fn)
         return as_value(relay->getAlphaOffset());
     }
     
-    relay->setAlphaOffset(fn.arg(0).to_number());
+    relay->setAlphaOffset(toNumber(fn.arg(0), getVM(fn)));
        return as_value();
 }
 
@@ -182,7 +182,7 @@ colortransform_blueMultiplier(const fn_call& fn)
         return as_value(relay->getBlueMultiplier());
     }
     
-    relay->setBlueMultiplier(fn.arg(0).to_number());
+    relay->setBlueMultiplier(toNumber(fn.arg(0), getVM(fn)));
        return as_value();
 }
 
@@ -194,7 +194,7 @@ colortransform_blueOffset(const fn_call& fn)
         return as_value(relay->getBlueOffset());
     }
     
-    relay->setBlueOffset(fn.arg(0).to_number());
+    relay->setBlueOffset(toNumber(fn.arg(0), getVM(fn)));
        return as_value();
 }
 
@@ -206,7 +206,7 @@ colortransform_greenMultiplier(const fn_call& fn)
         return as_value(relay->getGreenMultiplier());
     }
     
-    relay->setGreenMultiplier(fn.arg(0).to_number());
+    relay->setGreenMultiplier(toNumber(fn.arg(0), getVM(fn)));
        return as_value();
 }
 
@@ -219,7 +219,7 @@ colortransform_greenOffset(const fn_call& fn)
         return as_value(relay->getGreenOffset());
     }
     
-    relay->setGreenOffset(fn.arg(0).to_number());
+    relay->setGreenOffset(toNumber(fn.arg(0), getVM(fn)));
        return as_value();
 }
 
@@ -232,7 +232,7 @@ colortransform_redMultiplier(const fn_call& fn)
         return as_value(relay->getRedMultiplier());
     }
     
-    relay->setRedMultiplier(fn.arg(0).to_number());
+    relay->setRedMultiplier(toNumber(fn.arg(0), getVM(fn)));
        return as_value();
 }
 
@@ -247,7 +247,7 @@ colortransform_redOffset(const fn_call& fn)
     }
     
     // Setter
-    relay->setRedOffset(fn.arg(0).to_number());
+    relay->setRedOffset(toNumber(fn.arg(0), getVM(fn)));
        return as_value();
 }
 
@@ -386,14 +386,14 @@ colortransform_ctor(const fn_call& fn)
         );
     }
 
-       obj->setRelay(new ColorTransform_as(fn.arg(0).to_number(),
-                                        fn.arg(1).to_number(),
-                                        fn.arg(2).to_number(),
-                                        fn.arg(3).to_number(),
-                                        fn.arg(4).to_number(),
-                                        fn.arg(5).to_number(),
-                                        fn.arg(6).to_number(),
-                                        fn.arg(7).to_number()));
+       obj->setRelay(new ColorTransform_as(toNumber(fn.arg(0), getVM(fn)),
+                                        toNumber(fn.arg(1), getVM(fn)),
+                                        toNumber(fn.arg(2), getVM(fn)),
+                                        toNumber(fn.arg(3), getVM(fn)),
+                                        toNumber(fn.arg(4), getVM(fn)),
+                                        toNumber(fn.arg(5), getVM(fn)),
+                                        toNumber(fn.arg(6), getVM(fn)),
+                                        toNumber(fn.arg(7), getVM(fn))));
 
     return as_value();
 }
diff --git a/libcore/asobj/flash/geom/Matrix_as.cpp 
b/libcore/asobj/flash/geom/Matrix_as.cpp
index 0024b08..5e70c01 100644
--- a/libcore/asobj/flash/geom/Matrix_as.cpp
+++ b/libcore/asobj/flash/geom/Matrix_as.cpp
@@ -272,11 +272,11 @@ matrix_createBox(const fn_call& fn)
         case 4:
             tx = fn.arg(3);
         case 3:
-            rotation = fn.arg(2).to_number();
+            rotation = toNumber(fn.arg(2), getVM(fn));
         case 2:
             // There must be a minimum of 2 arguments.
-            scaleY = fn.arg(1).to_number();
-            scaleX = fn.arg(0).to_number();
+            scaleY = toNumber(fn.arg(1), getVM(fn));
+            scaleX = toNumber(fn.arg(0), getVM(fn));
             break;
     }
     
@@ -332,11 +332,11 @@ matrix_createGradientBox(const fn_call& fn)
         case 4:
             tx = fn.arg(3);
         case 3:
-            rotation = fn.arg(2).to_number();
+            rotation = toNumber(fn.arg(2), getVM(fn));
         case 2:
             // There must be a minimum of 2 arguments.
-            widthY = fn.arg(1).to_number();
-            widthX = fn.arg(0).to_number();
+            widthY = toNumber(fn.arg(1), getVM(fn));
+            widthX = toNumber(fn.arg(0), getVM(fn));
             break;
     }
     
@@ -526,7 +526,7 @@ matrix_rotate(const fn_call& fn)
     // Make rotation matrix
     boost::numeric::ublas::c_matrix<double, 2, 2> transformMatrix;
     
-    const double rot = fn.arg(0).to_number();
+    const double rot = toNumber(fn.arg(0), getVM(fn));
     
     transformMatrix(0, 0) = std::cos(rot);
     transformMatrix(0, 1) = std::sin(rot);
@@ -600,8 +600,8 @@ matrix_scale(const fn_call& fn)
     // Make scale matrix
     boost::numeric::ublas::c_matrix<double, 2, 2> transformMatrix;
     
-    const double scaleX = fn.arg(0).to_number();
-    const double scaleY = fn.arg(1).to_number();
+    const double scaleX = toNumber(fn.arg(0), getVM(fn));
+    const double scaleY = toNumber(fn.arg(1), getVM(fn));
     
     transformMatrix(0, 0) = scaleX;
     transformMatrix(0, 1) = 0.0;
@@ -774,8 +774,8 @@ matrix_translate(const fn_call& fn)
         ptr->get_member(NSV::PROP_TX, &tx);
         ptr->get_member(NSV::PROP_TY, &ty);
 
-        double transX = fn.arg(0).to_number() + tx.to_number();
-        double transY = fn.arg(1).to_number() + ty.to_number();
+        double transX = toNumber(fn.arg(0), getVM(fn)) + tx.to_number();
+        double transY = toNumber(fn.arg(1), getVM(fn)) + ty.to_number();
                 
         ptr->set_member(NSV::PROP_TX, as_value(transX));
         ptr->set_member(NSV::PROP_TY, as_value(transY));
diff --git a/libcore/vm/Machine.cpp b/libcore/vm/Machine.cpp
index af7de15..6dd0e24 100644
--- a/libcore/vm/Machine.cpp
+++ b/libcore/vm/Machine.cpp
@@ -865,7 +865,7 @@ Machine::execute()
                     if (!_stack.top(0).is_number()) throw ASException();
 
                     boost::uint32_t index =
-                        _stack.top(0).to_number();
+                        toNumber(_stack.top(0), getVM(fn));
                     _stack.drop(1);
 
                     mStream->seekBy(3); // Skip the intial offset.
@@ -954,7 +954,7 @@ Machine::execute()
                     ENSURE_OBJECT(_stack.top(1));
                     as_object *obj = _stack.top(1).to_object(*_global);
                     const boost::uint32_t index =
-                        _stack.top(0).to_number();
+                        toNumber(_stack.top(0), getVM(fn));
                     
                     if (!obj) {
                         // TODO: check what to do here.
@@ -986,7 +986,7 @@ Machine::execute()
                     ENSURE_OBJECT(_stack.top(1));
                     as_object *obj = _stack.top(1).to_object(*_global);
                     boost::uint32_t index =
-                        _stack.top(0).to_number();
+                        toNumber(_stack.top(0), getVM(fn));
                     _stack.drop(1);
                     assert(obj);
                     _stack.top(0) = obj->nextIndex(index);
@@ -1026,7 +1026,7 @@ Machine::execute()
                     ENSURE_OBJECT(_stack.top(1));
                     as_object *obj = _stack.top(1).to_object(*_global);
                     const boost::uint32_t index =
-                        _stack.top(0).to_number();
+                        toNumber(_stack.top(0), getVM(fn));
                     const Property *b = obj->getByIndex(index);
                     _stack.drop(1);
                     if (!b) _stack.top(0).set_undefined();
@@ -2228,7 +2228,7 @@ Machine::execute()
                 case SWF::ABC_ACTION_CONVERT_U:
                 case SWF::ABC_ACTION_COERCE_U:
                     _stack.top(0) = static_cast<boost::uint32_t>(
-                            _stack.top(0).to_number());
+                            toNumber(_stack.top(0), getVM(fn)));
                     break;
 
                 /// 0x75 ABC_ACTION_CONVERT_D
@@ -2239,7 +2239,7 @@ Machine::execute()
                 ///  double_value -- value as a double object
                 case SWF::ABC_ACTION_CONVERT_D:
                 case SWF::ABC_ACTION_COERCE_D:
-                    _stack.top(0) = _stack.top(0).to_number();
+                    _stack.top(0) = toNumber(_stack.top(0), getVM(fn));
                     break;
 
                 /// 0x76 ABC_ACTION_CONVERT_B
@@ -2391,7 +2391,7 @@ Machine::execute()
             ///  negdouble -- -1.0 * (double) obj
                 case SWF::ABC_ACTION_NEGATE:
                 {
-                    _stack.top(0) = -_stack.top(0).to_number();
+                    _stack.top(0) = -toNumber(_stack.top(0), getVM(fn));
                     break;
                 }
             /// 0x91 ABC_ACTION_INCREMENT
@@ -2412,7 +2412,7 @@ Machine::execute()
                 case SWF::ABC_ACTION_INCLOCAL:
                 {
                     boost::uint32_t foff = mStream->read_V32();
-                    setRegister(foff, getRegister(foff).to_number() + 1);
+                    setRegister(foff, toNumber(getRegister(foff), getVM(fn)) + 
1);
                     break;
                 }
 
@@ -2423,7 +2423,7 @@ Machine::execute()
                 ///  num - 1
                 case SWF::ABC_ACTION_DECREMENT:
                 {
-                    _stack.top(0) = _stack.top(0).to_number() - 1;
+                    _stack.top(0) = toNumber(_stack.top(0), getVM(fn)) - 1;
                     break;
                 }
 
@@ -2433,7 +2433,7 @@ Machine::execute()
                 case SWF::ABC_ACTION_DECLOCAL:
                 {
                     const boost::uint32_t foff = mStream->read_V32();
-                    setRegister(foff, getRegister(foff).to_number() - 1);
+                    setRegister(foff, toNumber(getRegister(foff), getVM(fn)) - 
1);
                     break;
                 }
 
@@ -2493,7 +2493,7 @@ Machine::execute()
                 /// Stack Out:
                 ///  a * b (double)
                 case SWF::ABC_ACTION_MULTIPLY:
-                    _stack.top(1) = _stack.top(1).to_number() * 
_stack.top(0).to_number();
+                    _stack.top(1) = toNumber(_stack.top(1), getVM(fn)) * 
toNumber(_stack.top(0), getVM(fn));
                     _stack.drop(1);
                     break;
 
@@ -2504,7 +2504,7 @@ Machine::execute()
                 /// Stack Out:
                 ///  a / b (double)
                 case SWF::ABC_ACTION_DIVIDE:
-                    _stack.top(1) = _stack.top(1).to_number() / 
_stack.top(0).to_number();
+                    _stack.top(1) = toNumber(_stack.top(1), getVM(fn)) / 
toNumber(_stack.top(0), getVM(fn));
                     _stack.drop(1);
                     break;
 
@@ -2517,10 +2517,10 @@ Machine::execute()
                 case SWF::ABC_ACTION_MODULO:
                 {
                     // TODO: test this properly and fix the UB (overflow).
-                    double result = _stack.top(1).to_number() / 
_stack.top(0).to_number();
+                    double result = toNumber(_stack.top(1), getVM(fn)) / 
toNumber(_stack.top(0), getVM(fn));
                     int trunc_result = static_cast<int> (result);
-                    _stack.top(1) = _stack.top(1).to_number() - 
-                        (trunc_result * _stack.top(0).to_number());
+                    _stack.top(1) = toNumber(_stack.top(1), getVM(fn)) - 
+                        (trunc_result * toNumber(_stack.top(0), getVM(fn)));
                     _stack.drop(1);
                     break;
                 }
@@ -2560,7 +2560,7 @@ Machine::execute()
                 case SWF::ABC_ACTION_URSHIFT:
                 {
                     _stack.top(1) =
-                        static_cast<boost::uint32_t>(_stack.top(1).to_number())
+                        static_cast<boost::uint32_t>(toNumber(_stack.top(1), 
getVM(fn)))
                         >> toInt(_stack.top(0));
                     _stack.drop(1);
                     break;

http://git.savannah.gnu.org/cgit//commit/?id=767fd1e85c317a56ab53b89d8c3f6909d13417fe


commit 767fd1e85c317a56ab53b89d8c3f6909d13417fe
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Oct 7 18:12:23 2010 +0200

    Minor cleanups

diff --git a/libcore/as_value.cpp b/libcore/as_value.cpp
index 57dc830..eb48969 100644
--- a/libcore/as_value.cpp
+++ b/libcore/as_value.cpp
@@ -320,7 +320,7 @@ as_value::to_number() const
 }
 
 double
-as_value::to_number(const int swfversion) const
+as_value::to_number(const int version) const
 {
 
     switch (_type) {
@@ -328,10 +328,10 @@ as_value::to_number(const int swfversion) const
         {
             const std::string& s = getStr();
             if ( s.empty() ) {
-                return swfversion >= 5 ? NaN : 0.0;
+                return version >= 5 ? NaN : 0.0;
             }
             
-            if (swfversion <= 4)
+            if (version <= 4)
             {
                 // For SWF4, any valid number before non-numerical
                 // DisplayObjects is returned, including exponent, positive
@@ -344,7 +344,7 @@ as_value::to_number(const int swfversion) const
 
             try {
 
-                if (swfversion > 5) {
+                if (version > 5) {
                     double d;
                     // Will throw if invalid.
                     if (parseNonDecimalInt(s, d)) return d;
@@ -377,7 +377,7 @@ as_value::to_number(const int swfversion) const
         {
             // Evan: from my tests
             // Martin: FlashPlayer6 gives 0; FP9 gives NaN.
-            return (swfversion >= 7 ? NaN : 0);
+            return (version >= 7 ? NaN : 0);
         }
 
         case BOOLEAN: 
@@ -395,7 +395,7 @@ as_value::to_number(const int swfversion) const
             // Arrays and Movieclips should return NaN.
             try {
                 as_value ret = to_primitive(NUMBER);
-                return ret.to_number();
+                return ret.to_number(version);
             }
             catch (ActionTypeError& e)
             {
@@ -403,7 +403,7 @@ as_value::to_number(const int swfversion) const
                 log_debug(_("to_primitive(%s, NUMBER) threw an "
                             "ActionTypeError %s"), *this, e.what());
 #endif
-                if (is_function() && swfversion < 6) {
+                if (is_function() && version < 6) {
                     return 0;
                 }
                 
@@ -1002,7 +1002,8 @@ compareBoolean(const as_value& boolean, const as_value& 
other)
 }
 
 bool
-stringEqualsNumber(const as_value& str, const as_value& num) {
+stringEqualsNumber(const as_value& str, const as_value& num)
+{
     assert(num.is_number());
     assert(str.is_string());
     const double n = str.to_number();
diff --git a/libcore/as_value.h b/libcore/as_value.h
index 76b0c06..06c05f4 100644
--- a/libcore/as_value.h
+++ b/libcore/as_value.h
@@ -430,15 +430,6 @@ private:
     ///
     bool equalsSameType(const as_value& v) const;
     
-    /// Conversion to boolean for SWF7 and up
-    bool to_bool_v7() const;
-    
-    /// Conversion to boolean for SWF6
-    bool to_bool_v6() const;
-    
-    /// Conversion to boolean up to SWF5
-    bool to_bool_v5() const;
-    
     AsType _type;
     
     AsValueType _value;

http://git.savannah.gnu.org/cgit//commit/?id=df57ebaa3f9f28e5f243c6e5646e28ba72b03834


commit df57ebaa3f9f28e5f243c6e5646e28ba72b03834
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Oct 7 17:52:49 2010 +0200

    Drop to_bool() usage.

diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index c61fa7e..36b6ff3 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -311,10 +311,13 @@ bool
 Button::trackAsMenu()
 {
     // TODO: check whether the AS or the tag value takes precedence.
+    as_object* obj = getObject(this);
+    assert(obj);
+
     as_value track;
-    string_table& st = getStringTable(*getObject(this));
-    if (getObject(this)->get_member(st.find("trackAsMenu"), &track)) {
-        return track.to_bool();
+    string_table& st = getStringTable(*obj);
+    if (obj->get_member(st.find("trackAsMenu"), &track)) {
+        return toBool(track, getVM(*obj));
     }
     if (_def) return _def->trackAsMenu();
     return false;
@@ -323,10 +326,13 @@ Button::trackAsMenu()
 bool 
 Button::isEnabled()
 {
+    as_object* obj = getObject(this);
+    assert(obj);
+
     as_value enabled;
-    if (!getObject(this)->get_member(NSV::PROP_ENABLED, &enabled)) return 
false;
+    if (!obj->get_member(NSV::PROP_ENABLED, &enabled)) return false;
 
-    return enabled.to_bool();
+    return toBool(enabled, getVM(*obj));
 }
 
 
diff --git a/libcore/DisplayObject.cpp b/libcore/DisplayObject.cpp
index cbe4fb3..26b4e63 100644
--- a/libcore/DisplayObject.cpp
+++ b/libcore/DisplayObject.cpp
@@ -739,15 +739,16 @@ DisplayObject::markReachableResources() const
 bool
 DisplayObject::allowHandCursor() const
 {
-    if (!getObject(this)) return false;
+    as_object* obj = getObject(this);
+    if (!obj) return false;
 
     if (!hasEventHandler(event_id::RELEASE)) return false;
 
     as_value val;
-    if (!getObject(this)->get_member(NSV::PROP_USEHANDCURSOR, &val)) {
+    if (!obj->get_member(NSV::PROP_USEHANDCURSOR, &val)) {
          return true;
     }
-    return val.to_bool();
+    return toBool(val, getVM(*obj));
 }
 
 void
diff --git a/libcore/ExternalInterface.cpp b/libcore/ExternalInterface.cpp
index a7d7af7..9d4813b 100644
--- a/libcore/ExternalInterface.cpp
+++ b/libcore/ExternalInterface.cpp
@@ -188,7 +188,7 @@ ExternalInterface::toXML(const as_value &val)
     } else if (val.is_exception()) {
         ss << "<exception>" << val.to_string()<< "</exception>";
     } else if (val.is_bool()) {
-        ss << (val.to_bool() ? "<true/>" : "<false/>");
+        ss << (val.to_bool(8) ? "<true/>" : "<false/>");
         // Function also isn't listed, but it's the only other type
         // supported by as_value, so leaving it out doesn't seem right.
     } else if (val.is_function()) {
diff --git a/libcore/as_value.cpp b/libcore/as_value.cpp
index a8795e7..57dc830 100644
--- a/libcore/as_value.cpp
+++ b/libcore/as_value.cpp
@@ -424,13 +424,6 @@ as_value::to_number(const int swfversion) const
     }
 }
 
-bool
-as_value::to_bool() const
-{
-    const int version = VM::get().getSWFVersion();
-    return to_bool(version);
-}
-
 // Conversion to boolean 
 bool
 as_value::to_bool(const int version) const
@@ -960,9 +953,9 @@ convertToString(as_value& v, const VM& vm)
 
 /// Force type to bool.
 as_value&
-convertToBoolean(as_value& v, const VM& /*vm*/)
+convertToBoolean(as_value& v, const VM& vm)
 {
-    v.set_bool(v.to_bool());
+    v.set_bool(v.to_bool(vm.getSWFVersion()));
     return v;
 }
 
diff --git a/libcore/as_value.h b/libcore/as_value.h
index c0a99ea..76b0c06 100644
--- a/libcore/as_value.h
+++ b/libcore/as_value.h
@@ -241,7 +241,6 @@ public:
     /// Conversion to boolean.
     //
     /// This function performs conversion if necessary.
-    bool to_bool() const;
     bool to_bool(int version) const;
     
     /// Return value as an object, converting primitive values as needed.
diff --git a/libcore/asobj/Boolean_as.cpp b/libcore/asobj/Boolean_as.cpp
index 8701dce..f00fa57 100644
--- a/libcore/asobj/Boolean_as.cpp
+++ b/libcore/asobj/Boolean_as.cpp
@@ -118,10 +118,10 @@ boolean_ctor(const fn_call& fn)
 
     if (!fn.isInstantiation()) {
         if (!fn.nargs) return as_value();
-        return as_value(fn.arg(0).to_bool());
+        return as_value(toBool(fn.arg(0), getVM(fn)));
     }
 
-    const bool val = fn.nargs ? fn.arg(0).to_bool() : false;
+    const bool val = fn.nargs ? toBool(fn.arg(0), getVM(fn)) : false;
 
     as_object* obj = fn.this_ptr;
     obj->setRelay(new Boolean_as(val));
diff --git a/libcore/asobj/Camera_as.cpp b/libcore/asobj/Camera_as.cpp
index aff962d..fad8c4e 100644
--- a/libcore/asobj/Camera_as.cpp
+++ b/libcore/asobj/Camera_as.cpp
@@ -299,7 +299,7 @@ camera_setmode(const fn_call& fn)
     const double width = nargs ? fn.arg(0).to_number() : 160;
     const double height = nargs > 1 ? fn.arg(1).to_number() : 120;
     const double fps = nargs >  2? fn.arg(2).to_number() : 15;
-    const bool favorArea = nargs > 3 ? fn.arg(3).to_bool() : true;
+    const bool favorArea = nargs > 3 ? toBool(fn.arg(3), getVM(fn)) : true;
 
     // TODO: handle overflow
     const size_t reqWidth = std::max<double>(width, 0);
@@ -586,7 +586,7 @@ camera_setLoopback(const fn_call& fn)
         log_aserror("%s: Too many arguments", "Camera.setLoopback");
     }
 
-    ptr->setLoopback(fn.arg(0).to_bool());
+    ptr->setLoopback(toBool(fn.arg(0), getVM(fn)));
     
     return as_value();
 }
diff --git a/libcore/asobj/Microphone_as.cpp b/libcore/asobj/Microphone_as.cpp
index 55954c7..2914079 100644
--- a/libcore/asobj/Microphone_as.cpp
+++ b/libcore/asobj/Microphone_as.cpp
@@ -465,7 +465,7 @@ microphone_setuseechosuppression(const fn_call& fn)
     if (!fn.nargs) {
         return as_value();
     }
-    ptr->setUseEchoSuppression(fn.arg(0).to_bool());
+    ptr->setUseEchoSuppression(toBool(fn.arg(0), getVM(fn)));
     return as_value();
 }
 
diff --git a/libcore/asobj/MovieClip_as.cpp b/libcore/asobj/MovieClip_as.cpp
index d3539bc..7f2d705 100644
--- a/libcore/asobj/MovieClip_as.cpp
+++ b/libcore/asobj/MovieClip_as.cpp
@@ -1019,11 +1019,13 @@ movieclip_hitTest(const fn_call& fn)
 
         case 3: // x, y, shapeFlag
         {
-             boost::int32_t x = pixelsToTwips(fn.arg(0).to_number());
-             boost::int32_t y = pixelsToTwips(fn.arg(1).to_number());
-             bool shapeFlag = fn.arg(2).to_bool();
+             const boost::int32_t x = pixelsToTwips(toNumber(fn.arg(0),
+                         getVM(fn)));
+             const boost::int32_t y = pixelsToTwips(toNumber(fn.arg(1),
+                         getVM(fn)));
+             const bool shapeFlag = toBool(fn.arg(2), getVM(fn));
 
-             if ( ! shapeFlag ) return movieclip->pointInBounds(x, y);
+             if (!shapeFlag) return movieclip->pointInBounds(x, y);
              else return movieclip->pointInHitableShape(x, y);
         }
 
@@ -1590,7 +1592,7 @@ movieclip_lineStyle(const fn_call& fn)
             }
         }
         case 4:
-            pixelHinting = fn.arg(3).to_bool();
+            pixelHinting = toBool(fn.arg(3), getVM(fn));
         case 3:
         {
             const float alphaval = clamp<float>(fn.arg(2).to_number(),
@@ -1892,7 +1894,7 @@ movieclip_startDrag(const fn_call& fn)
 
     if ( fn.nargs )
     {
-        st.setLockCentered( fn.arg(0).to_bool() );
+        st.setLockCentered(toBool(fn.arg(0), getVM(fn)));
 
         if ( fn.nargs >= 5)
         {
@@ -1988,12 +1990,14 @@ movieclip_beginBitmapFill(const fn_call& fn)
 
     BitmapFill::Type t = BitmapFill::TILED;
     if (fn.nargs > 2) {
-        const bool repeat = fn.arg(2).to_bool();
+        const bool repeat = toBool(fn.arg(2), getVM(fn));
         if (!repeat) t = BitmapFill::CLIPPED;
     }
 
     BitmapFill::SmoothingPolicy p = BitmapFill::SMOOTHING_OFF;
-    if (fn.nargs > 3 && fn.arg(3).to_bool()) p = BitmapFill::SMOOTHING_ON;
+    if (fn.nargs > 3 && toBool(fn.arg(3), getVM(fn))) {
+        p = BitmapFill::SMOOTHING_ON;
+    }
 
     // This is needed to get the bitmap to the right size and have it in the
     // correct place. Maybe it would be better handled somewhere else, as it's
@@ -2114,7 +2118,7 @@ movieclip_lockroot(const fn_call& fn)
         return as_value(ptr->getLockRoot());
     }
     
-    ptr->setLockRoot(fn.arg(0).to_bool());
+    ptr->setLockRoot(toBool(fn.arg(0), getVM(fn)));
     return as_value();
 }
     
diff --git a/libcore/asobj/NetStream_as.cpp b/libcore/asobj/NetStream_as.cpp
index 11231c6..b4ea388 100644
--- a/libcore/asobj/NetStream_as.cpp
+++ b/libcore/asobj/NetStream_as.cpp
@@ -1654,10 +1654,9 @@ netstream_pause(const fn_call& fn)
     
     // mode: -1 ==> toogle, 0==> pause, 1==> play
     NetStream_as::PauseMode mode = NetStream_as::pauseModeToggle;
-    if (fn.nargs > 0)
-    {
-        mode = fn.arg(0).to_bool() ? NetStream_as::pauseModePause :
-                                     NetStream_as::pauseModeUnPause;
+    if (fn.nargs > 0) {
+        mode = toBool(fn.arg(0), getVM(fn)) ? NetStream_as::pauseModePause :
+                                              NetStream_as::pauseModeUnPause;
     }
     
     // Toggle pause mode
diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index 60bbe98..10e4cdb 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -1157,7 +1157,7 @@ sound_loadsound(const fn_call& fn)
 
     bool streaming = false;
     if ( fn.nargs > 1 ) {
-        streaming = fn.arg(1).to_bool();
+        streaming = toBool(fn.arg(1), getVM(fn));
 
         IF_VERBOSE_ASCODING_ERRORS(
         if ( fn.nargs > 2 )
diff --git a/libcore/asobj/Stage_as.cpp b/libcore/asobj/Stage_as.cpp
index 4392e02..397af4f 100644
--- a/libcore/asobj/Stage_as.cpp
+++ b/libcore/asobj/Stage_as.cpp
@@ -204,7 +204,7 @@ stage_showMenu(const fn_call& fn)
     LOG_ONCE(log_unimpl("Stage.showMenu implemented by setting gnashrc "
                 "option and for gtk only"));
 
-    bool state = fn.arg(0).to_bool();
+    const bool state = toBool(fn.arg(0), getVM(fn));
     
     m.setShowMenuState(state);
     return as_value();
diff --git a/libcore/asobj/TextField_as.cpp b/libcore/asobj/TextField_as.cpp
index 4f6cfb4..25a97de 100644
--- a/libcore/asobj/TextField_as.cpp
+++ b/libcore/asobj/TextField_as.cpp
@@ -286,7 +286,7 @@ textfield_background(const fn_call& fn)
         return as_value(ptr->getDrawBackground());
     }
     else {
-        ptr->setDrawBackground(fn.arg(0).to_bool());
+        ptr->setDrawBackground(toBool(fn.arg(0), getVM(fn)));
     }
 
     return as_value();
@@ -301,7 +301,7 @@ textfield_border(const fn_call& fn)
         return as_value(ptr->getDrawBorder());
     }
     else {
-        ptr->setDrawBorder(fn.arg(0).to_bool());
+        ptr->setDrawBorder(toBool(fn.arg(0), getVM(fn)));
     }
 
     return as_value();
@@ -371,7 +371,7 @@ textfield_embedFonts(const fn_call& fn)
     }
 
     // Setter
-    ptr->setEmbedFonts(fn.arg(0).to_bool());
+    ptr->setEmbedFonts(toBool(fn.arg(0), getVM(fn)));
     return as_value();
 }
 
@@ -384,7 +384,7 @@ textfield_wordWrap(const fn_call& fn)
         return as_value(ptr->doWordWrap());
     }
     else {
-        ptr->setWordWrap(fn.arg(0).to_bool());
+        ptr->setWordWrap(toBool(fn.arg(0), getVM(fn)));
     }
 
     return as_value();
@@ -399,7 +399,7 @@ textfield_html(const fn_call& fn)
         return as_value(ptr->doHtml());
     }
     else {
-        ptr->setHtml( fn.arg(0).to_bool() );
+        ptr->setHtml( toBool(fn.arg(0), getVM(fn)) );
     }
 
     return as_value();
@@ -416,7 +416,7 @@ textfield_selectable(const fn_call& fn)
     }
     else // setter
     {
-        ptr->setSelectable( fn.arg(0).to_bool() );
+        ptr->setSelectable( toBool(fn.arg(0), getVM(fn)) );
     }
 
     return as_value();
@@ -508,7 +508,7 @@ textfield_autoSize(const fn_call& fn)
     {
         const as_value& arg = fn.arg(0);
         if (arg.is_bool()) {
-            if (arg.to_bool()) {
+            if (toBool(arg, getVM(fn))) {
                 // True equates to left, every other bool to none.
                 ptr->setAutoSize(TextField::AUTOSIZE_LEFT);
             }
@@ -744,7 +744,7 @@ textfield_password(const fn_call& fn)
         return as_value(text->password());
     }
     // Setter
-    text->password(fn.arg(0).to_bool());
+    text->password(toBool(fn.arg(0), getVM(fn)));
     return as_value();
 }
 
@@ -758,7 +758,7 @@ textfield_multiline(const fn_call& fn)
         return as_value(text->multiline());
     }
     // Setter
-    text->multiline(fn.arg(0).to_bool());
+    text->multiline(toBool(fn.arg(0), getVM(fn)));
     return as_value();
 }
 
diff --git a/libcore/asobj/TextFormat_as.cpp b/libcore/asobj/TextFormat_as.cpp
index ef67b69..d97dd78 100644
--- a/libcore/asobj/TextFormat_as.cpp
+++ b/libcore/asobj/TextFormat_as.cpp
@@ -83,7 +83,7 @@ ToBool : SetBase
 {
     ToBool(const fn_call& fn) : SetBase(fn) {}
     bool operator()(const as_value& val) const {
-        return val.to_bool();
+        return toBool(val, getVM(fn()));
     }
 };
 
@@ -420,11 +420,11 @@ textformat_new(const fn_call& fn)
            case 7:
                tf->urlSet(fn.arg(6).to_string());
            case 6:
-               tf->underlinedSet(fn.arg(5).to_bool());
+               tf->underlinedSet(toBool(fn.arg(5), getVM(fn)));
            case 5:
-               tf->italicSet(fn.arg(4).to_bool());
+               tf->italicSet(toBool(fn.arg(4), getVM(fn)));
            case 4:
-               tf->boldSet(fn.arg(3).to_bool());
+               tf->boldSet(toBool(fn.arg(3), getVM(fn)));
            case 3:
            {
                rgba col;
diff --git a/libcore/asobj/TextSnapshot_as.cpp 
b/libcore/asobj/TextSnapshot_as.cpp
index 340aeca..1293132 100644
--- a/libcore/asobj/TextSnapshot_as.cpp
+++ b/libcore/asobj/TextSnapshot_as.cpp
@@ -529,7 +529,7 @@ textsnapshot_findText(const fn_call& fn)
 
     /// Yes, the pp is case-insensitive by default. We don't write
     /// functions like that here.
-    bool ignoreCase = !fn.arg(2).to_bool();
+    const bool ignoreCase = !toBool(fn.arg(2), getVM(fn));
 
     return ts->findText(start, text, ignoreCase);
 }
@@ -581,7 +581,7 @@ textsnapshot_getSelectedText(const fn_call& fn)
         return as_value();
     }
 
-    bool newlines = fn.nargs ? fn.arg(0).to_bool() : false;
+    const bool newlines = fn.nargs ? toBool(fn.arg(0), getVM(fn)) : false;
 
     return as_value(ts->getSelectedText(newlines));
 }
@@ -605,7 +605,7 @@ textsnapshot_getText(const fn_call& fn)
     boost::int32_t start = toInt(fn.arg(0));
     boost::int32_t end = toInt(fn.arg(1));
 
-    const bool newline = (fn.nargs > 2) ? fn.arg(2).to_bool() : false;
+    const bool newline = (fn.nargs > 2) ? toBool(fn.arg(2), getVM(fn)) : false;
 
     return ts->getText(start, end, newline);
 
@@ -647,10 +647,10 @@ textsnapshot_setSelected(const fn_call& fn)
         return as_value();
     }
 
-    size_t start = std::max<boost::int32_t>(0, toInt(fn.arg(0)));
-    size_t end = std::max<boost::int32_t>(start, toInt(fn.arg(1)));
+    const size_t start = std::max<boost::int32_t>(0, toInt(fn.arg(0)));
+    const size_t end = std::max<boost::int32_t>(start, toInt(fn.arg(1)));
 
-    bool selected = (fn.nargs > 2) ? fn.arg(2).to_bool() : true;
+    const bool selected = (fn.nargs > 2) ? toBool(fn.arg(2), getVM(fn)) : true;
 
     ts->setSelected(start, end, selected);
 
diff --git a/libcore/asobj/XMLNode_as.cpp b/libcore/asobj/XMLNode_as.cpp
index 0a4b7b6..2c68b4f 100644
--- a/libcore/asobj/XMLNode_as.cpp
+++ b/libcore/asobj/XMLNode_as.cpp
@@ -627,7 +627,7 @@ xmlnode_cloneNode(const fn_call& fn)
     XMLNode_as* ptr = ensure<ThisIsNative<XMLNode_as> >(fn);
 
     bool deep = false;
-    if (fn.nargs > 0) deep = fn.arg(0).to_bool();
+    if (fn.nargs > 0) deep = toBool(fn.arg(0), getVM(fn));
 
     as_object* newnode = ptr->cloneNode(deep)->object();
     return as_value(newnode);
diff --git a/libcore/asobj/XML_as.cpp b/libcore/asobj/XML_as.cpp
index a199948..6b2102f 100644
--- a/libcore/asobj/XML_as.cpp
+++ b/libcore/asobj/XML_as.cpp
@@ -521,10 +521,13 @@ XML_as::ignoreWhite()
     const string_table::key propnamekey =
         getStringTable(_global).find("ignoreWhite");
     as_value val;
-    if (!object()->get_member(propnamekey, &val)) {
+
+    as_object* obj = object();
+
+    if (!obj->get_member(propnamekey, &val)) {
         return false;
     }
-    return val.to_bool();
+    return toBool(val, getVM(*obj));
 }
 
 // XML.prototype is assigned after the class has been constructed, so it
@@ -658,7 +661,7 @@ xml_loaded(const fn_call& fn)
         return as_value(static_cast<bool>(ls));
     }
     ptr->setLoaded(
-            static_cast<XML_as::LoadStatus>(fn.arg(0).to_bool()));
+            static_cast<XML_as::LoadStatus>(toBool(fn.arg(0), getVM(fn))));
     return as_value();
 }
 
diff --git a/libcore/asobj/flash/display/BitmapData_as.cpp 
b/libcore/asobj/flash/display/BitmapData_as.cpp
index 5e1620b..977fd01 100644
--- a/libcore/asobj/flash/display/BitmapData_as.cpp
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp
@@ -881,7 +881,7 @@ bitmapdata_ctor(const fn_call& fn)
 
     size_t width = toInt(fn.arg(0));
     size_t height = toInt(fn.arg(1));
-    const bool transparent = fn.nargs > 2 ? fn.arg(2).to_bool() : true;
+    const bool transparent = fn.nargs > 2 ? toBool(fn.arg(2), getVM(fn)) : 
true;
     boost::uint32_t fillColor = fn.nargs > 3 ? toInt(fn.arg(3)) : 0xffffffff;
     
     if (width > 2880 || height > 2880 || width < 1 || height < 1) {
diff --git a/libcore/asobj/flash/filters/BevelFilter_as.cpp 
b/libcore/asobj/flash/filters/BevelFilter_as.cpp
index 296f571..d70f680 100644
--- a/libcore/asobj/flash/filters/BevelFilter_as.cpp
+++ b/libcore/asobj/flash/filters/BevelFilter_as.cpp
@@ -220,7 +220,7 @@ bevelfilter_knockout(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_knockout );
     }
-    bool sp_knockout = fn.arg(0).to_bool ();
+    const bool sp_knockout = toBool(fn.arg(0), getVM(fn));
     ptr->m_knockout = sp_knockout;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/DropShadowFilter_as.cpp 
b/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
index 882bc26..4c255fe 100644
--- a/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
+++ b/libcore/asobj/flash/filters/DropShadowFilter_as.cpp
@@ -193,7 +193,7 @@ dropshadowfilter_knockout(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_knockout );
     }
-    bool sp_knockout = fn.arg(0).to_bool ();
+    const bool sp_knockout = toBool(fn.arg(0), getVM(fn));
     ptr->m_knockout = sp_knockout;
     return as_value();
 }
@@ -205,7 +205,7 @@ dropshadowfilter_inner(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_inner );
     }
-    bool sp_inner = fn.arg(0).to_bool ();
+    const bool sp_inner = toBool(fn.arg(0), getVM(fn));
     ptr->m_inner = sp_inner;
     return as_value();
 }
@@ -218,7 +218,7 @@ dropshadowfilter_hideObject(const fn_call& fn)
     if (fn.nargs == 0) {
         return as_value(ptr->m_hideObject );
     }
-    bool sp_hideObject = fn.arg(0).to_bool ();
+    const bool sp_hideObject = toBool(fn.arg(0), getVM(fn));
     ptr->m_hideObject = sp_hideObject;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/GlowFilter_as.cpp 
b/libcore/asobj/flash/filters/GlowFilter_as.cpp
index 333ede1..ac3140f 100644
--- a/libcore/asobj/flash/filters/GlowFilter_as.cpp
+++ b/libcore/asobj/flash/filters/GlowFilter_as.cpp
@@ -171,7 +171,7 @@ glowfilter_knockout(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_knockout );
     }
-    bool sp_knockout = fn.arg(0).to_bool ();
+    const bool sp_knockout = toBool(fn.arg(0), getVM(fn));
     ptr->m_knockout = sp_knockout;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp 
b/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
index 81b32a3..5b8a3ee 100644
--- a/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
+++ b/libcore/asobj/flash/filters/GradientBevelFilter_as.cpp
@@ -193,7 +193,7 @@ gradientbevelfilter_knockout(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_knockout );
     }
-    bool sp_knockout = fn.arg(0).to_bool ();
+    const bool sp_knockout = toBool(fn.arg(0), getVM(fn));
     ptr->m_knockout = sp_knockout;
     return as_value();
 }
diff --git a/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp 
b/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
index b203245..f3c4c2b 100644
--- a/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
+++ b/libcore/asobj/flash/filters/GradientGlowFilter_as.cpp
@@ -194,7 +194,7 @@ gradientglowfilter_knockout(const fn_call& fn)
     if (fn.nargs == 0) {
                return as_value(ptr->m_knockout );
     }
-    bool sp_knockout = fn.arg(0).to_bool ();
+    const bool sp_knockout = toBool(fn.arg(0), getVM(fn));
     ptr->m_knockout = sp_knockout;
     return as_value();
 }
diff --git a/libcore/asobj/flash/geom/Rectangle_as.cpp 
b/libcore/asobj/flash/geom/Rectangle_as.cpp
index 8072dec..3cf1587 100644
--- a/libcore/asobj/flash/geom/Rectangle_as.cpp
+++ b/libcore/asobj/flash/geom/Rectangle_as.cpp
@@ -207,19 +207,19 @@ Rectangle_contains(const fn_call& fn)
 
     as_value ret = newLessThan(x_as, rect_x_as, vm);
     if ( ret.is_undefined() ) return as_value();
-    if ( ret.to_bool() ) return as_value(false); 
+    if ( toBool(ret, vm) ) return as_value(false); 
 
     ret = newLessThan(x_as, rect_x1_as, vm);
     if ( ret.is_undefined() ) return as_value();
-    if ( ! ret.to_bool() ) return as_value(false); 
+    if ( ! toBool(ret, vm) ) return as_value(false); 
 
     ret = newLessThan(y_as, rect_y_as, vm);
     if ( ret.is_undefined() ) return as_value();
-    if ( ret.to_bool() ) return as_value(false); 
+    if ( toBool(ret, vm) ) return as_value(false); 
 
     ret = newLessThan(y_as, rect_y1_as, vm);
     if ( ret.is_undefined() ) return as_value();
-    if ( ! ret.to_bool() ) return as_value(false); 
+    if ( ! toBool(ret, vm) ) return as_value(false); 
 
     return as_value(true);
 
@@ -244,7 +244,7 @@ Rectangle_containsPoint(const fn_call& fn)
     // argx >= thisx
     as_value ret = newLessThan(argx, thisx, vm);
     if (ret.is_undefined()) return as_value(); 
-    if (ret.to_bool()) return as_value(false); 
+    if (toBool(ret, vm)) return as_value(false); 
 
     as_value thisw;
     ptr->get_member(NSV::PROP_WIDTH, &thisw);
@@ -252,7 +252,7 @@ Rectangle_containsPoint(const fn_call& fn)
     newAdd(thisx, thisw, vm);
     ret = newLessThan(argx, thisx, vm);
     if (ret.is_undefined()) return as_value(); 
-    if (!ret.to_bool()) return as_value(false); 
+    if (!toBool(ret, vm)) return as_value(false); 
  
     as_value thisy;
     ptr->get_member(NSV::PROP_Y, &thisy);
@@ -262,7 +262,7 @@ Rectangle_containsPoint(const fn_call& fn)
     // argy >= thisy
     ret = newLessThan(argy, thisy, vm);
     if (ret.is_undefined()) return as_value(); 
-    if (ret.to_bool()) return as_value(false); 
+    if (toBool(ret, vm)) return as_value(false); 
 
     as_value thish;
     ptr->get_member(NSV::PROP_HEIGHT, &thish);
@@ -270,7 +270,7 @@ Rectangle_containsPoint(const fn_call& fn)
     newAdd(thisy, thish, vm);
     ret = newLessThan(argy, thisy, vm);
     if (ret.is_undefined()) return as_value(); 
-    if (!ret.to_bool()) return as_value(false); 
+    if (!toBool(ret, vm)) return as_value(false); 
 
     return as_value(true);
 
@@ -344,10 +344,10 @@ Rectangle_isEmpty(const fn_call& fn)
     ptr->get_member(NSV::PROP_HEIGHT, &h);
     if ( h.is_undefined() || h.is_null() ) return as_value(true);
 
-    double wn = w.to_number();
+    double wn = toNumber(w, getVM(fn));
     if (!isFinite(wn) || wn <= 0) return as_value(true);
 
-    double hn = h.to_number();
+    double hn = toNumber(h, getVM(fn));
     if (!isFinite(hn) || hn <= 0) return as_value(true);
 
     log_debug("Width: %g, Height: %g", wn, hn);

http://git.savannah.gnu.org/cgit//commit/?id=a26699161c963370b8bd42027120e12ee48fbc7f


commit a26699161c963370b8bd42027120e12ee48fbc7f
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Oct 7 16:29:03 2010 +0200

    Use conversion functions in MovieClip.

diff --git a/libcore/MovieClip.cpp b/libcore/MovieClip.cpp
index d5234f1..f52ad14 100644
--- a/libcore/MovieClip.cpp
+++ b/libcore/MovieClip.cpp
@@ -460,18 +460,15 @@ MovieClip::get_frame_number(const as_value& frame_spec, 
size_t& frameno) const
 
     as_value str(fspecStr);
 
-    double num = str.to_number();
-
-    //log_debug("get_frame_number(%s), num: %g", frame_spec, num);
+    const double num = toNumber(str, getVM(*getObject(this)));
 
     if (!isFinite(num) || int(num) != num || num == 0)
     {
         bool ret = _def->get_labeled_frame(fspecStr, frameno);
-        //log_debug("get_labeled_frame(%s) returned %d, frameno is %d", 
fspecStr, ret, frameno);
         return ret;
     }
 
-    if ( num < 0 ) return false;
+    if (num < 0) return false;
 
     // all frame numbers > 0 are valid, but a valid frame number may still
     // reference a non-exist frame(eg. frameno > total_frames).
@@ -1285,12 +1282,15 @@ bool
 MovieClip::handleFocus()
 {
 
+    as_object* obj = getObject(this);
+    assert(obj);
+
     // For SWF6 and above: the MovieClip can always receive focus if
     // focusEnabled evaluates to true.
-    if (getSWFVersion(*getObject(this)) > 5) {
+    if (getSWFVersion(*obj) > 5) {
         as_value focusEnabled;
-        if (getObject(this)->get_member(NSV::PROP_FOCUS_ENABLED, 
&focusEnabled)) {
-            if (focusEnabled.to_bool() == true) return true; 
+        if (obj->get_member(NSV::PROP_FOCUS_ENABLED, &focusEnabled)) {
+            if (toBool(focusEnabled, getVM(*obj))) return true; 
         }
     }
         
@@ -1541,9 +1541,14 @@ MovieClip::findDropTarget(boost::int32_t x, 
boost::int32_t y,
 bool
 MovieClip::trackAsMenu()
 {
+    as_object* obj = getObject(this);
+    assert(obj);
+
+    string_table& st = getStringTable(*obj);
+
     as_value track;
-    string_table& st = getStringTable(*getObject(this));
-    return (getObject(this)->get_member(st.find("trackAsMenu"), &track) && 
track.to_bool());
+    return (obj->get_member(st.find("trackAsMenu"), &track) &&
+            toBool(track, getVM(*obj)));
 }
 
 bool
@@ -2018,12 +2023,15 @@ MovieClip::getBounds() const
 bool
 MovieClip::isEnabled() const
 {
+    as_object* obj = getObject(this);
+    assert(obj);
+
     as_value enabled;
-    if (!getObject(this)->get_member(NSV::PROP_ENABLED, &enabled)) {
+    if (!obj->get_member(NSV::PROP_ENABLED, &enabled)) {
          // We're enabled if there's no 'enabled' member...
          return true;
     }
-    return enabled.to_bool();
+    return toBool(enabled, getVM(*obj));
 }
 
 class EnumerateVisitor {

http://git.savannah.gnu.org/cgit//commit/?id=5ee7efe3ec5d1570edf2807f1601185e9bba4d05


commit 5ee7efe3ec5d1570edf2807f1601185e9bba4d05
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Oct 7 16:23:45 2010 +0200

    Use conversion functions more.

diff --git a/libcore/vm/ASHandlers.cpp b/libcore/vm/ASHandlers.cpp
index 7378032..f7f7201 100644
--- a/libcore/vm/ASHandlers.cpp
+++ b/libcore/vm/ASHandlers.cpp
@@ -821,7 +821,8 @@ ActionLogicalAnd(ActionExec& thread)
     as_environment& env = thread.env;
     
     // Note: the order of evaluation of the && operands is specified.
-    env.top(1).set_bool(env.top(1).to_bool() && env.top(0).to_bool());
+    env.top(1).set_bool(toBool(env.top(1), getVM(env)) &&
+            toBool(env.top(0), getVM(env)));
     env.drop(1);
 }
 
@@ -831,7 +832,8 @@ ActionLogicalOr(ActionExec& thread)
     as_environment& env = thread.env;
     
     // Note: the order of evaluation of the || operands is specified.
-    env.top(1).set_bool(env.top(1).to_bool() || env.top(0).to_bool());
+    env.top(1).set_bool(toBool(env.top(1), getVM(env)) ||
+            toBool(env.top(0), getVM(env)));
     env.drop(1);
 }
 
@@ -840,7 +842,7 @@ ActionLogicalNot(ActionExec& thread)
 {
     as_environment& env = thread.env;
     
-    env.top(0).set_bool(! env.top(0).to_bool());
+    env.top(0).set_bool(!toBool(env.top(0), getVM(env)));
 
     // Flash4 used 1 and 0 as return from this tag
     if (env.get_version() < 5) convertToNumber(env.top(0), getVM(env));
@@ -1249,10 +1251,10 @@ ActionStartDragMovie(ActionExec& thread)
         );
     }
 
-    st.setLockCentered(env.top(1).to_bool());
+    st.setLockCentered(toBool(env.top(1), getVM(env)));
 
     // Handle bounds.
-    if (env.top(2).to_bool()) {
+    if (toBool(env.top(2), getVM(env))) {
         // strk: this works if we didn't drop any before, in
         // a contrary case (if we used pop(), which I suggest)
         // we must remember to updated this as required
@@ -2037,9 +2039,8 @@ ActionBranchIfTrue(ActionExec& thread)
 
     boost::int16_t offset = code.read_int16(pc+3);
 
-    bool test = env.pop().to_bool();
-    if (test)
-    {
+    const bool test = toBool(env.pop(), getVM(env));
+    if (test) {
         thread.adjustNextPC(offset);
 
         if (nextPC > stopPC)

http://git.savannah.gnu.org/cgit//commit/?id=b88ec353b054a013b5d533f216ca4344988a4fe9


commit b88ec353b054a013b5d533f216ca4344988a4fe9
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Oct 7 16:19:58 2010 +0200

    Use conversion functions.

diff --git a/libcore/vm/ASHandlers.cpp b/libcore/vm/ASHandlers.cpp
index 39a6fee..7378032 100644
--- a/libcore/vm/ASHandlers.cpp
+++ b/libcore/vm/ASHandlers.cpp
@@ -716,8 +716,8 @@ ActionAdd(ActionExec& thread)
 {
     as_environment& env = thread.env;
     
-    const double operand2 = env.top(0).to_number();
-    const double operand1 = env.top(1).to_number();
+    const double operand2 = toNumber(env.top(0), getVM(env));
+    const double operand1 = toNumber(env.top(1), getVM(env));
     env.top(1) = operand1 + operand2;
     env.drop(1);
 }
@@ -735,8 +735,8 @@ ActionMultiply(ActionExec& thread)
 {
     as_environment& env = thread.env;
     
-    const double operand2 = env.top(0).to_number();
-    const double operand1 = env.top(1).to_number();
+    const double operand2 = toNumber(env.top(0), getVM(env));
+    const double operand1 = toNumber(env.top(1), getVM(env));
     env.top(1) = operand1 * operand2;
     env.drop(1);
 }
@@ -751,8 +751,8 @@ ActionDivide(ActionExec& thread)
 {
     as_environment& env = thread.env;
     
-    const double operand2 = env.top(0).to_number();
-    const double operand1 = env.top(1).to_number();
+    const double operand2 = toNumber(env.top(0), getVM(env));
+    const double operand1 = toNumber(env.top(1), getVM(env));
 
     if (operand2 == 0) {
         if (env.get_version() < 5) {
@@ -787,8 +787,8 @@ ActionEqual(ActionExec& thread)
     assert(thread.atActionTag(SWF::ACTION_EQUAL)); // 0x0E
 #endif
 
-    const double op1 = env.top(0).to_number();
-    const double op2 = env.top(1).to_number();
+    const double op1 = toNumber(env.top(0), getVM(env));
+    const double op2 = toNumber(env.top(1), getVM(env));
 
     env.top(1).set_bool(op2 == op1);
 
@@ -804,8 +804,8 @@ ActionLessThan(ActionExec& thread)
     as_environment& env = thread.env;
     
     // NB: this unusual order is correct!
-    const double d2 = env.top(1).to_number();
-    const double d1 = env.top(0).to_number();
+    const double d2 = toNumber(env.top(1), getVM(env));
+    const double d1 = toNumber(env.top(0), getVM(env));
 
     env.top(1).set_bool(d2 < d1);
 
@@ -1091,8 +1091,7 @@ ActionGetProperty(ActionExec& thread)
  
     // FIXME: what happens when it's an invalid number? This will cause
     // undefined behaviour on overflow.
-    unsigned int prop_number =
-        static_cast<unsigned int>(env.top(0).to_number());
+    unsigned int prop_number = toNumber(env.top(0), getVM(env));
 
     if (target) {
         getIndexedProperty(prop_number, *target, env.top(1));
@@ -1116,7 +1115,7 @@ ActionSetProperty(ActionExec& thread)
     DisplayObject *target = env.find_target(env.top(2).to_string());
     // FIXME: what happens when it's an invalid number? This will cause
     // undefined behaviour on overflow.
-    unsigned int prop_number = (unsigned int)env.top(1).to_number();
+    unsigned int prop_number = toNumber(env.top(1), getVM(env));
 
     as_value prop_val = env.top(0);
 
@@ -1139,7 +1138,7 @@ ActionDuplicateClip(ActionExec& thread)
 
     // Movies should be attachable from -16384 to 2130690044. See
     // Tests in misc-ming.all/DepthLimitsTest.c.
-    const double depth = env.top(0).to_number() +
+    const double depth = toNumber(env.top(0), getVM(env)) +
         DisplayObject::staticDepthOffset;
   
     // This also checks for overflow, as both numbers are expressible as
@@ -1257,10 +1256,10 @@ ActionStartDragMovie(ActionExec& thread)
         // strk: this works if we didn't drop any before, in
         // a contrary case (if we used pop(), which I suggest)
         // we must remember to updated this as required
-        boost::int32_t y1 = pixelsToTwips(env.top(3).to_number());
-        boost::int32_t x1 = pixelsToTwips(env.top(4).to_number());
-        boost::int32_t y0 = pixelsToTwips(env.top(5).to_number());
-        boost::int32_t x0 = pixelsToTwips(env.top(6).to_number());
+        boost::int32_t y1 = pixelsToTwips(toNumber(env.top(3), getVM(env)));
+        boost::int32_t x1 = pixelsToTwips(toNumber(env.top(4), getVM(env)));
+        boost::int32_t y0 = pixelsToTwips(toNumber(env.top(5), getVM(env)));
+        boost::int32_t x0 = pixelsToTwips(toNumber(env.top(6), getVM(env)));
 
         // check for swapped values
         if (y1 < y0) {
@@ -1385,7 +1384,7 @@ ActionImplementsOp(ActionExec& thread)
 
     as_value objval = env.pop();
     as_object* obj = toObject(getGlobal(thread.env), objval);
-    int count = static_cast<int>(env.pop().to_number());
+    int count = toNumber(env.pop(), getVM(env));
 
     if (!obj) {
         IF_VERBOSE_ASCODING_ERRORS(
@@ -2334,7 +2333,7 @@ ActionCallFunction(ActionExec& thread)
     // Get number of args, modifying it if not enough values are on the stack.
     // TODO: this may cause undefined behaviour if the number on the stack
     // is too large. Fix it.
-    size_t nargs = static_cast<size_t>(env.pop().to_number());
+    size_t nargs = toNumber(env.pop(), getVM(env));
     const size_t available_args = env.stack_size(); 
     if (available_args < nargs) {
         IF_VERBOSE_MALFORMED_SWF(
@@ -2393,12 +2392,11 @@ ActionModulo(ActionExec& thread)
     
     as_environment& env = thread.env;
 
-    as_value    result;
-    const double y = env.pop().to_number();
-    const double x = env.pop().to_number();
+    const double y = toNumber(env.pop(), getVM(env));
+    const double x = toNumber(env.pop(), getVM(env));
     // Don't need to check for y being 0 here - if it's zero,
     // fmod returns NaN, which is what flash would do too
-    result = std::fmod(x, y);
+    as_value result = std::fmod(x, y);
 
     env.push(result);
 }
@@ -2417,7 +2415,7 @@ ActionNew(ActionExec& thread)
             classname);
     );
 
-    unsigned nargs = unsigned(env.pop().to_number());
+    unsigned nargs = toNumber(env.pop(), getVM(env));
 
     as_value constructorval = thread.getVariable(classname);
     as_function* constructor = constructorval.to_function();
@@ -2787,14 +2785,14 @@ void
 ActionIncrement(ActionExec& thread)
 {
     as_environment& env = thread.env;
-    env.top(0).set_double(env.top(0).to_number() + 1);
+    env.top(0).set_double(toNumber(env.top(0), getVM(env)) + 1);
 }
 
 void
 ActionDecrement(ActionExec& thread)
 {
     as_environment& env = thread.env;
-    env.top(0).set_double(env.top(0).to_number() - 1);
+    env.top(0).set_double(toNumber(env.top(0), getVM(env)) - 1);
 }
 
 
@@ -2832,7 +2830,7 @@ ActionCallMethod(ActionExec& thread)
     as_value obj_value = env.pop();
 
     // Get number of args, modifying it if not enough values are on the stack.
-    size_t nargs = static_cast<size_t>(env.pop().to_number());
+    size_t nargs = toNumber(env.pop(), getVM(env));
     const size_t available_args = env.stack_size(); 
     if (available_args < nargs) {
         IF_VERBOSE_MALFORMED_SWF(
@@ -2984,7 +2982,7 @@ ActionNewMethod(ActionExec& thread)
     as_value obj_val = env.pop();
 
     // Get number of args, modifying it if not enough values are on the stack.
-    unsigned nargs = unsigned(env.pop().to_number());
+    unsigned nargs = toNumber(env.pop(), getVM(env));
     unsigned available_args = env.stack_size(); // previous 3 entries popped
     if (available_args < nargs) {
         IF_VERBOSE_MALFORMED_SWF(

http://git.savannah.gnu.org/cgit//commit/?id=9e0dc654e56972056eca60ab2730fe4a9b61af41


commit 9e0dc654e56972056eca60ab2730fe4a9b61af41
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Oct 7 16:12:00 2010 +0200

    Add VM functions for conversion.

diff --git a/libcore/Video.cpp b/libcore/Video.cpp
index 28785b8..2e9cca1 100644
--- a/libcore/Video.cpp
+++ b/libcore/Video.cpp
@@ -381,8 +381,7 @@ video_smoothing(const fn_call& fn)
 
     if (!fn.nargs) return as_value(video->smoothing());
 
-    bool smooth = fn.arg(0).to_bool();
-
+    const bool smooth = toBool(fn.arg(0), getVM(fn));
     video->setSmoothing(smooth);
 
     return as_value();
diff --git a/libcore/as_value.cpp b/libcore/as_value.cpp
index 4c1ca9f..a8795e7 100644
--- a/libcore/as_value.cpp
+++ b/libcore/as_value.cpp
@@ -315,11 +315,15 @@ as_value::to_primitive(AsType hint) const
 double
 as_value::to_number() const
 {
-
     const int swfversion = VM::get().getSWFVersion();
+    return to_number(swfversion);
+}
 
-    switch (_type)
-    {
+double
+as_value::to_number(const int swfversion) const
+{
+
+    switch (_type) {
         case STRING:
         {
             const std::string& s = getStr();
@@ -420,12 +424,17 @@ as_value::to_number() const
     }
 }
 
-
-// Conversion to boolean 
 bool
 as_value::to_bool() const
 {
     const int version = VM::get().getSWFVersion();
+    return to_bool(version);
+}
+
+// Conversion to boolean 
+bool
+as_value::to_bool(const int version) const
+{
     switch (_type)
     {
         case STRING:
@@ -935,15 +944,15 @@ doubleToString(double val, int radix)
 
 /// Force type to number.
 as_value&
-convertToNumber(as_value& v, VM& /*vm*/)
+convertToNumber(as_value& v, const VM& vm)
 {
-    v.set_double(v.to_number());
+    v.set_double(v.to_number(vm.getSWFVersion()));
     return v;
 }
 
 /// Force type to string.
 as_value&
-convertToString(as_value& v, VM& vm)
+convertToString(as_value& v, const VM& vm)
 {
     v.set_string(v.to_string(vm.getSWFVersion()));
     return v;
@@ -951,14 +960,14 @@ convertToString(as_value& v, VM& vm)
 
 /// Force type to bool.
 as_value&
-convertToBoolean(as_value& v, VM& /*vm*/)
+convertToBoolean(as_value& v, const VM& /*vm*/)
 {
     v.set_bool(v.to_bool());
     return v;
 }
 
 as_value&
-convertToPrimitive(as_value& v, VM& vm)
+convertToPrimitive(as_value& v, const VM& vm)
 {
     const as_value::AsType t(v.defaultPrimitive(vm.getSWFVersion()));
     v = v.to_primitive(t);
diff --git a/libcore/as_value.h b/libcore/as_value.h
index 4b91ba8..c0a99ea 100644
--- a/libcore/as_value.h
+++ b/libcore/as_value.h
@@ -236,11 +236,13 @@ public:
     //
     /// This function performs conversion if necessary.
     double to_number() const;
+    double to_number(int version) const;
     
     /// Conversion to boolean.
     //
     /// This function performs conversion if necessary.
     bool to_bool() const;
+    bool to_bool(int version) const;
     
     /// Return value as an object, converting primitive values as needed.
     //
@@ -484,16 +486,16 @@ private:
 };
 
 /// Force type to number.
-as_value& convertToNumber(as_value& v, VM& vm);
+as_value& convertToNumber(as_value& v, const VM& vm);
 
 /// Force type to string.
-as_value& convertToString(as_value& v, VM& vm);
+as_value& convertToString(as_value& v, const VM& vm);
 
 /// Force type to bool.
-as_value& convertToBoolean(as_value& v, VM& vm);
+as_value& convertToBoolean(as_value& v, const VM& vm);
 
 /// Convert to primitive type
-as_value& convertToPrimitive(as_value& v, VM& vm);
+as_value& convertToPrimitive(as_value& v, const VM& vm);
 
 /// Stream operator.
 std::ostream& operator<<(std::ostream& os, const as_value& v);
diff --git a/libcore/vm/VM.cpp b/libcore/vm/VM.cpp
index 900fa31..0eb26fc 100644
--- a/libcore/vm/VM.cpp
+++ b/libcore/vm/VM.cpp
@@ -415,7 +415,7 @@ VM::dumpState(std::ostream& out, size_t limit)
 ///////////////////////////////////////////////////////////////////////
 
 void
-newAdd(as_value& op1, const as_value& op2, VM& vm)
+newAdd(as_value& op1, const as_value& op2, const VM& vm)
 {
     // We can't change the original value.
     as_value r(op2);
@@ -444,22 +444,22 @@ newAdd(as_value& op1, const as_value& op2, VM& vm)
        }
 
     // Otherwise use numeric semantic
-    const double num1 = op1.to_number();
-    const double num2 = r.to_number();
+    const double num1 = toNumber(op1, vm);
+    const double num2 = toNumber(r, vm);
     op1.set_double(num2 + num1); 
 
 }
 
 void
-subtract(as_value& op1, const as_value& op2, VM& /*vm*/)
+subtract(as_value& op1, const as_value& op2, const VM& vm)
 {
-       const double num2 = op2.to_number();
-       const double num1 = op1.to_number();
+       const double num2 = toNumber(op2, vm);
+       const double num1 = toNumber(op1, vm);
        op1.set_double(num1 - num2);
 }
 
 as_value
-newLessThan(const as_value& op1, const as_value& op2, VM& /*vm*/)
+newLessThan(const as_value& op1, const as_value& op2, const VM& vm)
 {
 
     as_value operand1(op1);
@@ -496,8 +496,8 @@ newLessThan(const as_value& op1, const as_value& op2, VM& 
/*vm*/)
         return as_value(s1 < s2);
     }
 
-    const double num1 = operand1.to_number();
-    const double num2 = operand2.to_number();
+    const double num1 = toNumber(operand1, vm);
+    const double num2 = toNumber(operand2, vm);
 
     if (isNaN(num1) || isNaN(num2)) {
         return as_value();
@@ -505,6 +505,18 @@ newLessThan(const as_value& op1, const as_value& op2, VM& 
/*vm*/)
     return as_value(num1 < num2);
 }
 
+bool
+toBool(const as_value& v, const VM& vm)
+{
+    return v.to_bool(vm.getSWFVersion());
+}
+
+double
+toNumber(const as_value& v, const VM& vm)
+{
+    return v.to_number(vm.getSWFVersion());
+}
+
 } // end of namespace gnash
 
 
diff --git a/libcore/vm/VM.h b/libcore/vm/VM.h
index ca9dbca..8fde5fe 100644
--- a/libcore/vm/VM.h
+++ b/libcore/vm/VM.h
@@ -409,21 +409,25 @@ private:
 /// TODO:           Consider whether it would be better to pass something
 ///                 other than the VM. But it is a VM operation, so it
 ///                 is logically sound.
-void newAdd(as_value& op1, const as_value& op2, VM& vm);
+void newAdd(as_value& op1, const as_value& op2, const VM& vm);
 
 /// Carry out ActionSubtract
 //
 /// @param op1      The as_value to subtract from.
 /// @param op2      The as_value to subtract.
 /// @param vm       The VM executing the operation.
-void subtract(as_value& op1, const as_value& op2, VM& vm);
+void subtract(as_value& op1, const as_value& op2, const VM& vm);
 
 /// Carry out ActionSubtract
 //
 /// @param op1      The first comparand.
 /// @param op2      The second comparand.
 /// @param vm       The VM executing the operation.
-as_value newLessThan(const as_value& op1, const as_value& op2, VM& vm);
+as_value newLessThan(const as_value& op1, const as_value& op2, const VM& vm);
+
+bool toBool(const as_value& v, const VM& vm);
+
+double toNumber(const as_value& v, const VM& vm);
 
 } // namespace gnash
 

-----------------------------------------------------------------------

Summary of changes:
 extensions/fileio/fileio.cpp                       |    6 +-
 extensions/gtk2/gtkext.cpp                         |    4 +-
 libcore/Button.cpp                                 |   16 +-
 libcore/CharacterProxy.h                           |    1 +
 libcore/ClassHierarchy.cpp                         |   33 ----
 libcore/ClassHierarchy.h                           |    8 +-
 libcore/DisplayObject.cpp                          |   29 ++--
 libcore/ExternalInterface.cpp                      |    2 +-
 libcore/MovieClip.cpp                              |   32 ++--
 libcore/Video.cpp                                  |    3 +-
 libcore/as_value.cpp                               |  127 ++++---------
 libcore/as_value.h                                 |   36 +----
 libcore/asobj/ASConversions.cpp                    |   24 ++-
 libcore/asobj/Array_as.cpp                         |  199 ++++++++++----------
 libcore/asobj/AsBroadcaster.cpp                    |    5 +-
 libcore/asobj/Boolean_as.cpp                       |    4 +-
 libcore/asobj/Camera_as.cpp                        |   18 +-
 libcore/asobj/Color_as.cpp                         |    8 +-
 libcore/asobj/Date_as.cpp                          |   72 ++++----
 libcore/asobj/Global_as.cpp                        |   32 ++--
 libcore/asobj/Key_as.cpp                           |    2 +-
 libcore/asobj/LocalConnection_as.cpp               |    3 +-
 libcore/asobj/Math_as.cpp                          |   27 ++--
 libcore/asobj/Microphone_as.cpp                    |   10 +-
 libcore/asobj/MovieClip_as.cpp                     |   97 +++++-----
 libcore/asobj/NetStream_as.cpp                     |   11 +-
 libcore/asobj/Number_as.cpp                        |    4 +-
 libcore/asobj/Selection_as.cpp                     |    4 +-
 libcore/asobj/SharedObject_as.cpp                  |    2 +-
 libcore/asobj/Sound_as.cpp                         |    8 +-
 libcore/asobj/Stage_as.cpp                         |    2 +-
 libcore/asobj/String_as.cpp                        |   53 +++---
 libcore/asobj/TextField_as.cpp                     |   48 +++---
 libcore/asobj/TextFormat_as.cpp                    |   36 ++--
 libcore/asobj/TextSnapshot_as.cpp                  |   32 ++--
 libcore/asobj/XMLNode_as.cpp                       |    4 +-
 libcore/asobj/XMLSocket_as.cpp                     |    2 +-
 libcore/asobj/XML_as.cpp                           |   11 +-
 libcore/asobj/flash/display/BitmapData_as.cpp      |   39 ++--
 libcore/asobj/flash/filters/BevelFilter_as.cpp     |   22 +-
 libcore/asobj/flash/filters/BlurFilter_as.cpp      |    6 +-
 .../asobj/flash/filters/DropShadowFilter_as.cpp    |   22 +-
 libcore/asobj/flash/filters/GlowFilter_as.cpp      |   16 +-
 .../asobj/flash/filters/GradientBevelFilter_as.cpp |   14 +-
 .../asobj/flash/filters/GradientGlowFilter_as.cpp  |   14 +-
 libcore/asobj/flash/geom/ColorTransform_as.cpp     |   34 ++--
 libcore/asobj/flash/geom/Matrix_as.cpp             |  110 +++++------
 libcore/asobj/flash/geom/Point_as.cpp              |   42 ++--
 libcore/asobj/flash/geom/Rectangle_as.cpp          |   20 +-
 libcore/vm/ASHandlers.cpp                          |  125 ++++++------
 libcore/vm/Machine.cpp                             |   32 ++--
 libcore/vm/VM.cpp                                  |   88 ++++++++-
 libcore/vm/VM.h                                    |   35 +++-
 testsuite/libcore.all/AsValueTest.cpp              |  133 -------------
 testsuite/misc-ming.all/DefineTextTest-Runner.cpp  |    2 +-
 testsuite/misc-ming.all/DragDropTestRunner.cpp     |    2 +-
 .../PrototypeEventListenersTestRunner.cpp          |    2 +-
 testsuite/misc-ming.all/attachMovieTestRunner.cpp  |   10 +-
 testsuite/misc-ming.all/intervalTestRunner.cpp     |   34 ++--
 testsuite/misc-ming.all/loadMovieTestRunner.cpp    |    2 +-
 testsuite/misc-swfc.all/button_test1runner.cpp     |    2 +-
 .../movies.all/gravity_embedded-TestRunner.cpp     |   30 ++--
 62 files changed, 855 insertions(+), 996 deletions(-)


hooks/post-receive
-- 
Gnash



reply via email to

[Prev in Thread] Current Thread [Next in Thread]