gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r10894: Expose classes to enumeratio


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10894: Expose classes to enumeration as expected. Fixes bug #25081, as haxe
Date: Wed, 20 May 2009 13:46:53 +0200
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 10894
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2009-05-20 13:46:53 +0200
message:
  Expose classes to enumeration as expected. Fixes bug #25081, as haxe
  for some reason relies on enumerating classes onto the stack.
modified:
  libcore/as_object.cpp
  libcore/asobj/flash/display/BitmapData_as.cpp
  libcore/asobj/flash/display_pkg.cpp
  libcore/asobj/flash/external/ExternalInterface_as.cpp
  libcore/asobj/flash/external_pkg.cpp
  libcore/asobj/flash/filters/BitmapFilter_as.cpp
  libcore/asobj/flash/filters/ConvolutionFilter_as.cpp
  libcore/asobj/flash/filters_pkg.cpp
  libcore/asobj/flash/geom/ColorTransform_as.cpp
  libcore/asobj/flash/geom/Matrix_as.cpp
  libcore/asobj/flash/geom/Point_as.cpp
  libcore/asobj/flash/geom/Rectangle_as.cpp
  libcore/asobj/flash/geom/Transform_as.cpp
  libcore/asobj/flash/geom_pkg.cpp
  libcore/asobj/flash/net_pkg.cpp
  libcore/asobj/flash/text_pkg.cpp
  libcore/asobj/flash_pkg.cpp
  libcore/vm/ASHandlers.cpp
  libcore/vm/ActionExec.cpp
  testsuite/actionscript.all/enumerate.as
    ------------------------------------------------------------
    revno: 10885.1.1
    committer: Benjamin Wolsey <address@hidden>
    branch nick: test
    timestamp: Wed 2009-05-20 11:05:45 +0200
    message:
      Initial correct to some bugs identified by weird bytecode from haxe.
      
      Enumeration should push an undefined value, not null, as the end marker.
      
      Flash packages should not be hidden from enumeration (but it isn't clear
      exactly what they should be).
    modified:
      libcore/as_object.cpp
      libcore/asobj/flash/display_pkg.cpp
      libcore/asobj/flash/external_pkg.cpp
      libcore/asobj/flash/filters_pkg.cpp
      libcore/asobj/flash/geom_pkg.cpp
      libcore/asobj/flash/net_pkg.cpp
      libcore/asobj/flash/text_pkg.cpp
      libcore/asobj/flash_pkg.cpp
      libcore/vm/ASHandlers.cpp
      libcore/vm/ActionExec.cpp
    ------------------------------------------------------------
    revno: 10885.1.2
    committer: Benjamin Wolsey <address@hidden>
    branch nick: test
    timestamp: Wed 2009-05-20 12:37:32 +0200
    message:
      Add test for enumeration, especially the termination marker.
      
      Make all flash package members enumerable pending better tests.
    modified:
      libcore/asobj/flash/display/BitmapData_as.cpp
      libcore/asobj/flash/display_pkg.cpp
      libcore/asobj/flash/external/ExternalInterface_as.cpp
      libcore/asobj/flash/external_pkg.cpp
      libcore/asobj/flash/filters/BitmapFilter_as.cpp
      libcore/asobj/flash/filters/ConvolutionFilter_as.cpp
      libcore/asobj/flash/filters_pkg.cpp
      libcore/asobj/flash/geom/ColorTransform_as.cpp
      libcore/asobj/flash/geom/Matrix_as.cpp
      libcore/asobj/flash/geom/Point_as.cpp
      libcore/asobj/flash/geom/Rectangle_as.cpp
      libcore/asobj/flash/geom/Transform_as.cpp
      libcore/asobj/flash/geom_pkg.cpp
      libcore/asobj/flash/net_pkg.cpp
      libcore/asobj/flash/text_pkg.cpp
      testsuite/actionscript.all/enumerate.as
=== modified file 'libcore/as_object.cpp'
--- a/libcore/as_object.cpp     2009-05-14 11:45:23 +0000
+++ b/libcore/as_object.cpp     2009-05-20 09:05:45 +0000
@@ -311,10 +311,10 @@
        string_table::key nsname)
 {
        assert(val);
-
        Property* prop = findProperty(name, nsname);
-       if (!prop)
-    {
+       
+    if (!prop) {
+
         /// If the property isn't found, try the __resolve property.
         prop = findProperty(NSV::PROP_uuRESOLVE, nsname);
         if (!prop) return false;
@@ -329,18 +329,15 @@
         return true;
     }
 
-       try 
-       {
+       try {
                *val = prop->getValue(*this);
                return true;
        }
-       catch (ActionLimitException& exc)
-       {
+       catch (ActionLimitException& exc) {
                // will be logged by outer catcher
                throw;
        }
-       catch (ActionTypeError& exc)
-       {
+       catch (ActionTypeError& exc) {
                // TODO: check if this should be an 'as' error.. (log_aserror)
                log_error(_("Caught exception: %s"), exc.what());
                return false;
@@ -462,11 +459,10 @@
         // __proto__ even when not visible ?
                if (prop && prop->visible(swfVersion))
                {
-                       if (owner != NULL)
-                               *owner = this;
+                       if (owner) *owner = this;
                        return prop;
                }
-               return NULL;
+               return 0;
        }
 
        // keep track of visited objects, avoid infinite loops.
@@ -1042,7 +1038,7 @@
 void
 as_object::enumerateProperties(as_environment& env) const
 {
-       assert( env.top(0).is_null() );
+       assert(env.top(0).is_undefined());
 
        enumerateNonProperties(env);
 

=== modified file 'libcore/asobj/flash/display/BitmapData_as.cpp'
--- a/libcore/asobj/flash/display/BitmapData_as.cpp     2009-04-14 15:07:44 
+0000
+++ b/libcore/asobj/flash/display/BitmapData_as.cpp     2009-05-20 10:37:32 
+0000
@@ -241,9 +241,11 @@
 {
 
     string_table& st = where.getVM().getStringTable();
-       // Register _global.BitmapData
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
        where.init_destructive_property(st.find("BitmapData"),
-                       get_flash_display_bitmap_data_constructor);
+                get_flash_display_bitmap_data_constructor, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/display_pkg.cpp'
--- a/libcore/asobj/flash/display_pkg.cpp       2009-05-14 11:06:24 +0000
+++ b/libcore/asobj/flash/display_pkg.cpp       2009-05-20 10:37:32 +0000
@@ -47,8 +47,11 @@
 flash_display_package_init(as_object& where)
 {
        string_table& st = where.getVM().getStringTable();
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
        where.init_destructive_property(st.find("display"),
-                       get_flash_display_package);
+                       get_flash_display_package, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/external/ExternalInterface_as.cpp'
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp     2009-02-25 
22:33:03 +0000
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp     2009-05-20 
10:37:32 +0000
@@ -368,8 +368,11 @@
 {
     // Register _global.Point
     string_table& st = where.getVM().getStringTable();
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
     where.init_destructive_property(st.find("ExternalInterface"),
-            get_flash_external_external_interface_constructor);
+            get_flash_external_external_interface_constructor, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/external_pkg.cpp'
--- a/libcore/asobj/flash/external_pkg.cpp      2009-02-25 22:33:03 +0000
+++ b/libcore/asobj/flash/external_pkg.cpp      2009-05-20 10:37:32 +0000
@@ -43,7 +43,11 @@
 flash_external_package_init(as_object& where)
 {
        string_table& st = where.getVM().getStringTable();
-       where.init_destructive_property(st.find("external"), 
get_flash_external_package);
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+       where.init_destructive_property(st.find("external"),
+            get_flash_external_package, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/filters/BitmapFilter_as.cpp'
--- a/libcore/asobj/flash/filters/BitmapFilter_as.cpp   2009-04-23 07:16:23 
+0000
+++ b/libcore/asobj/flash/filters/BitmapFilter_as.cpp   2009-05-20 10:37:32 
+0000
@@ -47,8 +47,11 @@
 BitmapFilter_class_init(as_object& global)
 {
     string_table& st = global.getVM().getStringTable();
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
     global.init_destructive_property(st.find("BitmapFilter"),
-            getBitmapFilterConstructor);
+            getBitmapFilterConstructor, flags);
 }
 
 as_object*

=== modified file 'libcore/asobj/flash/filters/ConvolutionFilter_as.cpp'
--- a/libcore/asobj/flash/filters/ConvolutionFilter_as.cpp      2009-04-23 
07:16:23 +0000
+++ b/libcore/asobj/flash/filters/ConvolutionFilter_as.cpp      2009-05-20 
10:37:32 +0000
@@ -59,8 +59,11 @@
 ConvolutionFilter_class_init(as_object& global)
 {
     string_table& st = global.getVM().getStringTable();
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
     global.init_destructive_property(st.find("ConvolutionFilter"),
-            getConvolutionFilterConstructor);
+            getConvolutionFilterConstructor, flags);
 }
 
 as_object*

=== modified file 'libcore/asobj/flash/filters_pkg.cpp'
--- a/libcore/asobj/flash/filters_pkg.cpp       2009-02-25 22:33:03 +0000
+++ b/libcore/asobj/flash/filters_pkg.cpp       2009-05-20 10:37:32 +0000
@@ -61,7 +61,11 @@
 flash_filters_package_init(as_object& where)
 {
        string_table& st = where.getVM().getStringTable();
-       where.init_destructive_property(st.find("filters"), 
get_flash_filters_package);
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+       where.init_destructive_property(st.find("filters"),
+            get_flash_filters_package, flags);
 }
 
 

=== modified file 'libcore/asobj/flash/geom/ColorTransform_as.cpp'
--- a/libcore/asobj/flash/geom/ColorTransform_as.cpp    2009-02-27 11:55:27 
+0000
+++ b/libcore/asobj/flash/geom/ColorTransform_as.cpp    2009-05-20 10:37:32 
+0000
@@ -395,7 +395,11 @@
     // This is the ColorTransform "class"/"function"
     // in the 'where' package
     string_table& st = where.getVM().getStringTable();
-    where.init_destructive_property(st.find("ColorTransform"), 
get_flash_geom_color_transform_constructor);
+
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+    where.init_destructive_property(st.find("ColorTransform"),
+            get_flash_geom_color_transform_constructor, flags);
 }
 
 } // end of gnash namespace

=== modified file 'libcore/asobj/flash/geom/Matrix_as.cpp'
--- a/libcore/asobj/flash/geom/Matrix_as.cpp    2009-02-27 11:55:27 +0000
+++ b/libcore/asobj/flash/geom/Matrix_as.cpp    2009-05-20 10:37:32 +0000
@@ -916,7 +916,11 @@
     // This is going to be the Matrix "class"/"function"
     // in the 'where' package
     string_table& st = where.getVM().getStringTable();
-    where.init_destructive_property(st.find("Matrix"), 
get_flash_geom_matrix_constructor);
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+    where.init_destructive_property(st.find("Matrix"),
+            get_flash_geom_matrix_constructor, flags);
 }
 
 } // end of gnash namespace

=== modified file 'libcore/asobj/flash/geom/Point_as.cpp'
--- a/libcore/asobj/flash/geom/Point_as.cpp     2009-03-17 11:39:48 +0000
+++ b/libcore/asobj/flash/geom/Point_as.cpp     2009-05-20 10:37:32 +0000
@@ -681,7 +681,11 @@
 {
        // Register _global.Point
        string_table& st = where.getVM().getStringTable();
-       where.init_destructive_property(st.find("Point"), 
get_flash_geom_point_constructor);
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+       where.init_destructive_property(st.find("Point"),
+            get_flash_geom_point_constructor, flags);
 }
 
 } // end of gnash namespace

=== modified file 'libcore/asobj/flash/geom/Rectangle_as.cpp'
--- a/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-04-01 07:00:32 +0000
+++ b/libcore/asobj/flash/geom/Rectangle_as.cpp 2009-05-20 10:37:32 +0000
@@ -663,7 +663,11 @@
 {
        // Register _global.Rectangle
        string_table& st = where.getVM().getStringTable();
-       where.init_destructive_property(st.find("Rectangle"), 
get_flash_geom_rectangle_constructor);
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+       where.init_destructive_property(st.find("Rectangle"),
+            get_flash_geom_rectangle_constructor, flags);
 }
 
 } // end of gnash namespace

=== modified file 'libcore/asobj/flash/geom/Transform_as.cpp'
--- a/libcore/asobj/flash/geom/Transform_as.cpp 2009-04-03 09:18:40 +0000
+++ b/libcore/asobj/flash/geom/Transform_as.cpp 2009-05-20 10:37:32 +0000
@@ -422,8 +422,11 @@
 
        // Register _global.Transform
     string_table& st = where.getVM().getStringTable();
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
     where.init_destructive_property(st.find("Transform"), 
-                   get_flash_geom_transform_constructor);
+                   get_flash_geom_transform_constructor, flags);
 
 }
 

=== modified file 'libcore/asobj/flash/geom_pkg.cpp'
--- a/libcore/asobj/flash/geom_pkg.cpp  2009-02-25 22:33:03 +0000
+++ b/libcore/asobj/flash/geom_pkg.cpp  2009-05-20 10:37:32 +0000
@@ -51,7 +51,11 @@
 flash_geom_package_init(as_object& where)
 {
        string_table& st = where.getVM().getStringTable();
-       where.init_destructive_property(st.find("geom"), 
get_flash_geom_package);
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+       where.init_destructive_property(st.find("geom"), get_flash_geom_package,
+            flags);
 }
 
 

=== modified file 'libcore/asobj/flash/net_pkg.cpp'
--- a/libcore/asobj/flash/net_pkg.cpp   2009-02-25 22:33:03 +0000
+++ b/libcore/asobj/flash/net_pkg.cpp   2009-05-20 10:37:32 +0000
@@ -45,7 +45,11 @@
 flash_net_package_init(as_object& where)
 {
        string_table& st = where.getVM().getStringTable();
-       where.init_destructive_property(st.find("net"), get_flash_net_package);
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+       where.init_destructive_property(st.find("net"), get_flash_net_package, 
+            flags);
 }
 
 

=== modified file 'libcore/asobj/flash/text_pkg.cpp'
--- a/libcore/asobj/flash/text_pkg.cpp  2009-03-04 20:30:04 +0000
+++ b/libcore/asobj/flash/text_pkg.cpp  2009-05-20 10:37:32 +0000
@@ -47,7 +47,11 @@
 flash_text_package_init(as_object& where)
 {
        string_table& st = where.getVM().getStringTable();
-       where.init_destructive_property(st.find("text"), 
get_flash_text_package);
+    
+    // TODO: this may not be correct, but it should be enumerable.
+    const int flags = 0;
+       where.init_destructive_property(st.find("text"), get_flash_text_package,
+            flags);
 }
 
 

=== modified file 'libcore/asobj/flash_pkg.cpp'
--- a/libcore/asobj/flash_pkg.cpp       2009-05-14 12:34:16 +0000
+++ b/libcore/asobj/flash_pkg.cpp       2009-05-20 09:05:45 +0000
@@ -40,12 +40,12 @@
 
        // sub-packages:
        // TODO: use a destructive getter-setter for these 
+       flash_text_package_init(*pkg);
        flash_display_package_init(*pkg);
-       flash_external_package_init(*pkg);
        flash_filters_package_init(*pkg);
        flash_geom_package_init(*pkg);
        flash_net_package_init(*pkg);
-       flash_text_package_init(*pkg);
+       flash_external_package_init(*pkg);
        return pkg;
 }
 

=== modified file 'libcore/vm/ASHandlers.cpp'
--- a/libcore/vm/ASHandlers.cpp 2009-04-16 12:04:53 +0000
+++ b/libcore/vm/ASHandlers.cpp 2009-05-20 09:05:45 +0000
@@ -2996,11 +2996,11 @@
 // Push a each object's member value on the stack
 // This is an utility function for use by ActionEnumerate
 // and ActionEnum2. The caller is expected to have
-// already set the top-of-stack to the NULL value (as an optimization)
+// already set the top-of-stack to undefined (as an optimization)
 static void
 enumerateObject(as_environment& env, const as_object& obj)
 {
-    assert( env.top(0).is_null() );
+    assert(env.top(0).is_undefined());
     obj.enumerateProperties(env);
 }
 
@@ -3016,7 +3016,7 @@
 
     as_value variable = thread.getVariable(var_string);
 
-    env.top(0).set_null();
+    env.top(0).set_undefined();
 
     const boost::intrusive_ptr<as_object> obj = variable.to_object();
     if ( !obj || !variable.is_object() )
@@ -3490,8 +3490,7 @@
     // Get number of args, modifying it if not enough values are on the stack.
     unsigned nargs = unsigned(env.pop().to_number());
     unsigned available_args = env.stack_size(); // previous 3 entries popped
-    if ( available_args < nargs )
-    {
+    if (available_args < nargs) {
         IF_VERBOSE_MALFORMED_SWF(
         log_swferror(_("Attempt to call a constructor with %u arguments "
             "while only %u are available on the stack."),
@@ -3501,12 +3500,13 @@
     }
 
     boost::intrusive_ptr<as_object> obj = obj_val.to_object();
-    if ( ! obj )
-    {
+    if (!obj) {
         // SWF integrity check
         // FIXME, should this be log_swferror?  Or log_aserror?
-        log_error(_("On ActionNewMethod: "
-            "no object found on stack on ActionMethod"));
+        IF_VERBOSE_MALFORMED_SWF(
+            log_swferror(_("On ActionNewMethod: "
+                "no object found on stack on ActionMethod"));
+        );
         env.drop(nargs);
         env.push(as_value());
         return;
@@ -3514,35 +3514,29 @@
 
     std::string method_string = method_name.to_string();
     as_value method_val;
-    if ( method_name.is_undefined() || method_string.empty() )
-    {
+    if (method_name.is_undefined() || method_string.empty()) {
         method_val = obj_val;
     }
-    else
-    {
-        if ( ! thread.getObjectMember(*obj, method_string, method_val) )
-        {
+    else {
+        if (!thread.getObjectMember(*obj, method_string, method_val)) {
             IF_VERBOSE_ASCODING_ERRORS(
-            log_aserror(_("ActionNewMethod: "
-                "can't find method %s of object %s"),
-                method_string, obj_val);
+                log_aserror(_("ActionNewMethod: can't find method %s of "
+                        "object %s"), method_string, obj_val);
             );
             env.drop(nargs);
-            env.push(as_value()); // should we push an object anyway ?
+            env.push(as_value()); 
             return;
         }
     }
 
     boost::intrusive_ptr<as_function> method = method_val.to_as_function();
-    if ( ! method )
-    {
+    if (!method) {
         IF_VERBOSE_MALFORMED_SWF(
-        log_swferror(_("ActionNewMethod: "
-            "method name is undefined, "
-            "and object is not a function"));
+            log_swferror(_("ActionNewMethod: method name is undefined "
+                "and object is not a function"));
         );
         env.drop(nargs);
-        env.push(as_value()); // should we push an object anyway ?
+        env.push(as_value()); 
         return;
     }
 
@@ -3595,7 +3589,7 @@
 
     // End of the enumeration. Won't override the object
     // as we copied that as_value.
-    env.top(0).set_null();
+    env.top(0).set_undefined();
 
     const boost::intrusive_ptr<as_object> obj = obj_val.to_object();
     if ( !obj || !obj_val.is_object() )

=== modified file 'libcore/vm/ActionExec.cpp'
--- a/libcore/vm/ActionExec.cpp 2009-04-22 11:55:09 +0000
+++ b/libcore/vm/ActionExec.cpp 2009-05-20 09:05:45 +0000
@@ -739,17 +739,19 @@
 }
 
 void
-ActionExec::setObjectMember(as_object& obj, const std::string& var, const 
as_value& val)
+ActionExec::setObjectMember(as_object& obj, const std::string& var,
+        const as_value& val)
 {
     string_table& st = env.getVM().getStringTable();
-    obj.set_member(st.find(PROPNAME(var)), val);
+    obj.set_member(st.find(var), val);
 }
 
 bool
-ActionExec::getObjectMember(as_object& obj, const std::string& var, as_value& 
val)
+ActionExec::getObjectMember(as_object& obj, const std::string& var,
+        as_value& val)
 {
     string_table& st = env.getVM().getStringTable();
-    return obj.get_member(st.find(PROPNAME(var)), &val);
+    return obj.get_member(st.find(var), &val);
 }
 
 /*private*/

=== modified file 'testsuite/actionscript.all/enumerate.as'
--- a/testsuite/actionscript.all/enumerate.as   2009-02-25 22:33:03 +0000
+++ b/testsuite/actionscript.all/enumerate.as   2009-05-20 10:37:32 +0000
@@ -152,7 +152,108 @@
     check_equals(enumerateObj(o), "6,9,c,[object Object],b,el,a,");
 
 }
-totals(31);
+
+extras = 0;
+
+#ifdef MING_SUPPORTS_ASM
+ extras += 6;
+
+// The first test (enumerate) is possible with any asm-supporting ming, 
+// the second only with version from 2009-05-20 or later.
+ a = new Object();
+ a.a = 1;
+ a.b = "string";
+ 
+ var r0, r1, r2, r3, r4;
+ 
+ 
+ // We make sure the stack is clear, then push 'stackfirst', then enumerate
+ // and see what all the stack values are.
+ asm {
+    pop
+    pop
+    push 'stackfirst'
+    push 'a'
+    enumerate
+    setregister r:0
+    push 'r0', r:0
+    setvariable
+    pop
+    setregister r:1
+    push 'r1', r:1
+    setvariable
+    pop
+    setregister r:2
+    push 'r2', r:2
+    setvariable
+    pop
+    setregister r:3
+    push 'r3', r:3
+    setvariable
+    pop
+    setregister r:4
+    push 'r4', r:4
+    setvariable
+    pop
+ };
+ 
+ check_equals(r0, "b");
+ check_equals(r1, "a");
+ check_equals(r2, undefined);
+
+ // Use strictly equals to check that it isn't "null"
+ check(r2 === undefined);
+ 
+ check_equals(r3, "stackfirst");
+ check_equals(r4, undefined);
+#endif
+
+#if MING_VERSION_CODE >= 00040004 
+ extras += 6;
+ 
+ // Do the same for enum2
+ asm {
+    pop
+    pop
+    push 'stackfirst'
+    push 'a'
+    getvariable
+    enumerate2
+    setregister r:0
+    push 'r0', r:0
+    setvariable
+    pop
+    setregister r:1
+    push 'r1', r:1
+    setvariable
+    pop
+    setregister r:2
+    push 'r2', r:2
+    setvariable
+    pop
+    setregister r:3
+    push 'r3', r:3
+    setvariable
+    pop
+    setregister r:4
+    push 'r4', r:4
+    setvariable
+    pop
+ };
+ 
+ check_equals(r0, "b");
+ check_equals(r1, "a");
+ check_equals(r2, undefined);
+
+ // Use strictly equals to check that it isn't "null"
+ check(r2 === undefined);
+ 
+ check_equals(r3, "stackfirst");
+ check_equals(r4, undefined);
+#endif
+
+totals(31 + extras);
+
 #else
 totals(0);
 #endif  // OUTPUT_VERSION > 5


reply via email to

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