[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/as_environment.cpp serve...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/as_environment.cpp serve... |
Date: |
Mon, 15 Jan 2007 00:06:59 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 07/01/15 00:06:59
Modified files:
. : ChangeLog
server : as_environment.cpp as_environment.h
sprite_instance.cpp
server/vm : ASHandlers.cpp ActionExec.cpp ActionExec.h
testsuite/actionscript.all: getvariable.as
Log message:
* server/vm/ActionExec.{cpp,h} (getVariable, setVariable,
setLocalVariable): convert variable name to
lowercase if SWF version is < 7. This should relief us
from doing it in as_object::get_member_default (TODO: check
it out).
* server/sprite_instance.cpp (get_member):
handle '_root', '_level0' and 'this' references.
* server/vm/ASHandlers.cpp (CommonSetTarget): use
as_environment::get_variable() rather then find_target()
to resolve target name (more hiding, automatic use of the
new implementaion).
* server/as_environment.{cpp,h}: (get_variable):
allow objects to be used as path components, scan _global for
first element of path. Uses a newly added
find_object_slashsyntax
and find_object_dotsyntax methods, with interface similar to
find_target,
but w/out insisting on getting a sprite_instance.
(find_target): return NULL on invalid paths.
* testsuite/actionscript.all/getvariable.as: some new tests.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2105&r2=1.2106
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.cpp?cvsroot=gnash&r1=1.52&r2=1.53
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.h?cvsroot=gnash&r1=1.37&r2=1.38
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.123&r2=1.124
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ActionExec.cpp?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ActionExec.h?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/getvariable.as?cvsroot=gnash&r1=1.4&r2=1.5
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2105
retrieving revision 1.2106
diff -u -b -r1.2105 -r1.2106
--- ChangeLog 13 Jan 2007 23:22:58 -0000 1.2105
+++ ChangeLog 15 Jan 2007 00:06:58 -0000 1.2106
@@ -1,3 +1,23 @@
+2007-01-14 Sandro Santilli <address@hidden>
+
+ * server/vm/ActionExec.{cpp,h} (getVariable, setVariable,
+ setLocalVariable): convert variable name to
+ lowercase if SWF version is < 7. This should relief us
+ from doing it in as_object::get_member_default (TODO: check it out).
+ * server/sprite_instance.cpp (get_member):
+ handle '_root', '_level0' and 'this' references.
+ * server/vm/ASHandlers.cpp (CommonSetTarget): use
+ as_environment::get_variable() rather then find_target()
+ to resolve target name (more hiding, automatic use of the
+ new implementaion).
+ * server/as_environment.{cpp,h}: (get_variable):
+ allow objects to be used as path components, scan _global for
+ first element of path. Uses a newly added find_object_slashsyntax
+ and find_object_dotsyntax methods, with interface similar to
find_target,
+ but w/out insisting on getting a sprite_instance.
+ (find_target): return NULL on invalid paths.
+ * testsuite/actionscript.all/getvariable.as: some new tests.
+
2007-01-13 Sandro Santilli <address@hidden>
* testsuite/actionscript.all/Makefile.am: don't attempt to
Index: server/as_environment.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- server/as_environment.cpp 11 Jan 2007 23:17:48 -0000 1.52
+++ server/as_environment.cpp 15 Jan 2007 00:06:59 -0000 1.53
@@ -16,7 +16,7 @@
//
-/* $Id: as_environment.cpp,v 1.52 2007/01/11 23:17:48 strk Exp $ */
+/* $Id: as_environment.cpp,v 1.53 2007/01/15 00:06:59 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -29,6 +29,7 @@
#include "as_value.h"
#include "with_stack_entry.h"
#include "VM.h"
+#include "log.h"
#include <string>
#include <utility> // for std::pair
@@ -47,18 +48,37 @@
std::string path;
std::string var;
//log_msg("get_variable(%s)", varname.c_str());
- if (parse_path(varname, path, var)) {
+ bool is_slash_based;
+ if (parse_path(varname, path, var, &is_slash_based)) {
//as_value target_val = get_variable_raw(path, with_stack);
//as_object* target = target_val.to_object();
// TODO: let find_target return generic as_objects, or use 'with' stack,
- // see player2.swf or bug #18758
- as_object* target = find_target(path); // @@ we should likely use
with_stack here too ..
+ // see player2.swf or bug #18758 (strip.swf)
+ // @@ TODO: should we use with_stack here too ?
+ as_object* target = is_slash_based ? find_object_slashsyntax(path) :
find_object_dotsyntax(path);
+
if (target) {
as_value val;
target->get_member(var.c_str(), &val);
return val;
} else {
- log_error("find_target(\"%s\") failed", path.c_str());
+
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("find_object%s(\"%s\") [ varname = '%s' - current
target = '%s' ] failed",
+ is_slash_based ? "_slashsyntax" : "_dotsyntax",
+ path.c_str(),
+ varname.c_str(),
+ m_target->get_text_value()
+ );
+ );
+
+ as_value tmp = get_variable_raw(path, with_stack);
+ if ( ! tmp.is_undefined() )
+ {
+#ifdef DEBUG_GET_VARIABLE
+ log_msg("But get_variable_raw(%s, <with_stack>)
succeeded!", path.c_str());
+#endif
+ }
return as_value();
}
} else {
@@ -82,7 +102,7 @@
assert(strchr(varname.c_str(), ':') == NULL);
//let's allow slashes in variable names, if SWF has them..
//assert(strchr(varname.c_str(), '/') == NULL);
- assert(strchr(varname.c_str(), '.') == NULL);
+ ////assert(strchr(varname.c_str(), '.') == NULL);
as_value val;
@@ -207,12 +227,15 @@
);
// Path lookup rigamarole.
- character* target = m_target;
+ as_object* target = m_target;
std::string path;
std::string var;
//log_msg("set_variable(%s, %s)", varname.c_str(), val.to_string());
- if (parse_path(varname, path, var)) {
- target = find_target(path);
+ bool is_slash_based;
+ if (parse_path(varname, path, var, &is_slash_based)) {
+ //log_msg("Variable '%s' parsed into path='%s', var='%s'",
varname.c_str(), path.c_str(), var.c_str());
+ //target = find_target(path);
+ target = is_slash_based ? find_object_slashsyntax(path) :
find_object_dotsyntax(path);
if (target)
{
target->set_member(var.c_str(), val);
@@ -220,7 +243,7 @@
else
{
IF_VERBOSE_ASCODING_ERRORS(
- log_warning("Path target '%s' not found while setting %s=%s",
+ log_aserror("Path target '%s' not found while setting %s=%s",
path.c_str(), varname.c_str(), val.to_string());
);
}
@@ -367,7 +390,7 @@
/* public static */
bool
as_environment::parse_path(const std::string& var_path,
- std::string& path, std::string& var)
+ std::string& path, std::string& var, bool* is_slash_based)
{
//log_msg("parse_path(%s)", var_path.c_str());
// Search for colon.
@@ -375,6 +398,7 @@
int var_path_length = var_path.length();
for ( ; colon_index < var_path_length; colon_index++) {
if (var_path[colon_index] == ':') {
+ if ( is_slash_based ) *is_slash_based = true;
// Found it.
break;
}
@@ -386,6 +410,7 @@
for (colon_index = var_path_length - 1; colon_index >= 0;
colon_index--) {
if (var_path[colon_index] == '.') {
// Found it.
+ if ( is_slash_based ) *is_slash_based = false;
break;
}
}
@@ -442,7 +467,7 @@
{
// TODO: should we *force* string conversion above instead ?
IF_VERBOSE_ASCODING_ERRORS(
- log_warning("as_environment::find_target: '%s': "
+ log_aserror("as_environment::find_target: '%s': "
"invalid path; neither string nor object",
val.to_string());
);
@@ -466,6 +491,30 @@
return NULL;
}
+static const char*
+find_next_slash(const char* word)
+{
+ for (const char* p = word; *p; p++) {
+ if (*p == '/') {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+static const char*
+find_next_dot(const char* word)
+{
+ for (const char* p = word; *p; p++) {
+ if (*p == '.' ) {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
// Find the sprite/movie referenced by the given path.
//
// Supports both /slash/syntax and dot.syntax
@@ -513,8 +562,11 @@
const char* next_slash = next_slash_or_dot(p);
subpart = p;
if (next_slash == p) {
- log_error("invalid path '%s'", path.c_str());
- break;
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("invalid path '%s'", path.c_str());
+ );
+ return NULL;
+ //break;
} else if (next_slash) {
// Cut off the slash and everything after it.
subpart.resize(next_slash - p);
@@ -544,6 +596,249 @@
return env;
}
+as_object*
+as_environment::find_object_dotsyntax(const std::string& path) const
+{
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("find_object_dotsyntax(%s) called", path.c_str());
+#endif
+
+ if (path.length() <= 0) {
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Returning m_target (empty path)");
+#endif
+ return m_target;
+ }
+
+ // we'd have returned m_target in this case
+ //assert(path.length() > 0);
+
+ as_object* env = m_target;
+ assert(env);
+
+ if ( path.empty() ) {
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Null path, returning m_target");
+#endif
+ return env;
+ }
+
+ const char* p = path.c_str();
+ unsigned int depth=0; // number of iterations
+ while (env)
+ {
+ const char* next_dot = find_next_dot(p); // TODO: use std::string::find
+ std::string subpart = p;
+ if (next_dot == p) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("invalid path '%s'", path.c_str());
+ );
+ return NULL; // TODO: check me
+ //break;
+ } else if (next_dot) {
+ // Cut off the slash and everything after it.
+ subpart.resize(next_dot - p);
+ }
+
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Subpart == %s", subpart.c_str());
+#endif
+
+ // No more components to scan
+ if ( subpart.empty() )
+ {
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("No more subparts, env is %p", (void*)env);
+#endif
+ break;
+ }
+
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Invoking get_member(%s) on object %p", subpart.c_str(), (void
*)env);
+#endif
+ as_value tmp;
+ // TODO: make sure sprite_instances know about ".."
+ if ( ! env->get_member(subpart.c_str(), &tmp) )
+ {
+ // Try _global, but only at first iteration...
+ if ( depth > 0 )
+ {
+ log_msg("Member %s for object %p not found",
subpart.c_str(), env);
+ return NULL;
+ }
+
+ if ( ! VM::get().getGlobal()->get_member(subpart.c_str(), &tmp)
)
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("Element '%s' of variable '%s' not found in
object %p nor in _global",
+ subpart.c_str(), path.c_str(), env);
+ );
+ return NULL;
+ }
+ }
+
+ env = tmp.to_object();
+
+ // Debugging only:
+ if ( env == NULL ) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("Member %s for object %p found but doesn't cast to
an as_object", subpart.c_str(), env);
+ );
+ return NULL;
+ }
+
+ //@@ _level0 --> root, .. --> parent, . --> this, other == character
+
+ if (next_dot == NULL) {
+ break;
+ }
+
+ p = next_dot + 1;
+ ++depth;
+ }
+ return env;
+}
+
+as_object*
+as_environment::find_object_slashsyntax(const std::string& path) const
+{
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("find_object_slashsyntax(%s) called", path.c_str());
+#endif
+
+ if (path.length() <= 0) {
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Returning m_target (empty path)");
+#endif
+ return m_target;
+ }
+
+ // we'd have returned m_target in this case
+ //assert(path.length() > 0);
+
+ as_object* env = m_target;
+ assert(env);
+
+ const char* p = path.c_str();
+
+ if (*p == '/') {
+ // Absolute path. Start at the *absolute* root.
+ // TODO: should this be VM::get().getRoot().get_root_movie() ?
+ env = m_target->get_root_movie();
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Absolute path, start at the root (%p)", (void*)env);
+#endif
+ p++;
+ }
+
+ if (*p == '\0') {
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Null path, returning m_target");
+#endif
+ return env;
+ }
+
+ unsigned int depth=0; // number of iterations
+ while (env) {
+ std::string subpart;
+ const char* next_slash = find_next_slash(p); // TODO: use
std::string::find
+ subpart = p;
+ if (next_slash == p) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("invalid path '%s'", path.c_str());
+ );
+ return NULL; // TODO: check me
+ //break;
+ } else if (next_slash) {
+ // Cut off the slash and everything after it.
+ subpart.resize(next_slash - p);
+ }
+
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Subpart == %s", subpart.c_str());
+#endif
+
+ // No more components to scan
+ if ( subpart.empty() )
+ {
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("No more subparts, env is %p", (void*)env);
+#endif
+ break;
+ }
+
+ if ( subpart == ".." )
+ {
+ character* ch = dynamic_cast<character*>(env);
+ if ( ! ch ) {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("'..' element in path '%s' follows a
non-character object %p",
+ path.c_str(), env);
+ );
+ return NULL;
+ }
+ env = ch->get_parent();
+ if ( ! env ) // root movie doesn't have a parent
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("'..' in path '%s' follows a character with
no parent (%s : %p) (root is %p)",
+ path.c_str(), ch->get_text_value(), ch,
VM::get().getRoot().get_root_movie());
+ );
+ // if we override env, getvariable.as fails [line 57]
+ //env = ch;
+ }
+ }
+ else
+ {
+
+#ifdef DEBUG_TARGET_FINDING
+ log_msg("Invoking get_member(%s) on object %p",
subpart.c_str(), (void *)env);
+#endif
+ as_value tmp;
+ // TODO: make sure sprite_instances know about ".."
+ if ( ! env->get_member(subpart.c_str(), &tmp) )
+ {
+ // Try _global, but only at first iteration...
+ if ( depth > 0 )
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("Member %s for object %p not
found", subpart.c_str(), env);
+ );
+ return NULL;
+ }
+
+ if ( !
VM::get().getGlobal()->get_member(subpart.c_str(), &tmp) )
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("Element '%s' of variable '%s' not
found in object %p nor in _global",
+ subpart.c_str(), path.c_str(), env);
+ );
+ return NULL;
+ }
+ }
+
+ as_object* newenv = tmp.to_object();
+ // Debugging only:
+ if ( newenv == NULL ) {
+ log_msg("Member %s for object %p found but doesn't cast
to an as_object", subpart.c_str(), env);
+ return NULL;
+ }
+
+ env = newenv;
+ }
+
+ //@@ _level0 --> root, .. --> parent, . --> this, other == character
+
+ if (next_slash == NULL) {
+ break;
+ }
+
+ p = next_slash + 1;
+ ++depth;
+ }
+ return env;
+}
+
int
as_environment::get_version() const
{
Index: server/as_environment.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -b -r1.37 -r1.38
--- server/as_environment.h 9 Jan 2007 01:55:24 -0000 1.37
+++ server/as_environment.h 15 Jan 2007 00:06:59 -0000 1.38
@@ -18,7 +18,7 @@
//
//
-/* $Id: as_environment.h,v 1.37 2007/01/09 01:55:24 strk Exp $ */
+/* $Id: as_environment.h,v 1.38 2007/01/15 00:06:59 strk Exp $ */
#ifndef GNASH_AS_ENVIRONMENT_H
#define GNASH_AS_ENVIRONMENT_H
@@ -327,6 +327,9 @@
//
/// The value might be a reference to the object itself, or a
/// string giving a relative path name to the object.
+ ///
+ /// @@ make private ? --strk;
+ ///
character* find_target(const as_value& val) const;
/// Dump content of the stack to a std::ostream
@@ -378,8 +381,14 @@
//
// If no colon or dot, returns false and leaves *path & *var alone.
//
+ /// @param is_slash_based
+ /// If not null gets set to true if path is slash-based
+ /// (path/to/:variable), and to false if path is dot-based
+ /// (path.to.variable).
+ ///
+ /// TODO: return an integer: 0 not a path, 1 a slash-based path, 2 a
dot-based path
static bool parse_path(const std::string& var_path, std::string& path,
- std::string& var);
+ std::string& var, bool* is_slash_based=NULL);
/// The variables container (case-insensitive)
@@ -451,6 +460,22 @@
return m_local_frames.begin();
}
+ /// Find an object referenced by the given path (slash syntax).
+ //
+ /// Supports /slash/syntax
+ ///
+ /// Return NULL if path doesn't point to an object.
+ ///
+ as_object* find_object_slashsyntax(const std::string& path) const;
+
+ /// Find an object referenced by the given path (dot syntax).
+ //
+ /// Supports dot.syntax
+ ///
+ /// Return NULL if path doesn't point to an object.
+ ///
+ as_object* find_object_dotsyntax(const std::string& path) const;
+
};
Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -b -r1.123 -r1.124
--- server/sprite_instance.cpp 11 Jan 2007 21:24:42 -0000 1.123
+++ server/sprite_instance.cpp 15 Jan 2007 00:06:59 -0000 1.124
@@ -1211,10 +1211,31 @@
// Set *val to the value of the named member and
// return true, if we have the named member.
// Otherwise leave *val alone and return false.
-bool sprite_instance::get_member(const tu_stringi& name, as_value* val)
+bool sprite_instance::get_member(const tu_stringi& name_, as_value* val)
{
+ // TODO: take a std::string directly !!
+ std::string name = name_.c_str();
+
+ if ( name == "_root" )
+ {
+ // TODO: handle lockroot
+ val->set_as_object( VM::get().getRoot().get_root_movie() );
+ return true;
+ }
+ if ( name == "_level0" )
+ {
+ // TODO: handle _level# (any level)
+ val->set_as_object( VM::get().getRoot().get_root_movie() );
+ return true;
+ }
+ if ( name == "this" )
+ {
+ val->set_as_object( this );
+ return true;
+ }
+
// FIXME: use addProperty interface for these !!
- as_standard_member std_member = get_standard_member(name);
+ as_standard_member std_member = get_standard_member(name.c_str());
switch (std_member)
{
default:
@@ -1451,7 +1472,7 @@
} // end switch
// Try variables.
- if (m_as_environment.get_member(std::string(name.c_str()), val))
+ if ( m_as_environment.get_member(name, val) )
{
return true;
}
@@ -1459,7 +1480,9 @@
// Try object members, BEFORE display list items!
// (see testcase VarAndCharClash.swf in testsuite/misc-ming.all)
//
- if ( get_member_default(name, val) )
+ // TODO: simplify the next line when get_member_default takes
+ // a std::string
+ if ( get_member_default(name.c_str(), val) )
{
// ... trying to be useful to Flash coders ...
@@ -1470,7 +1493,7 @@
//#define CHECK_FOR_NAME_CLASHES 1
#ifdef CHECK_FOR_NAME_CLASHES
IF_VERBOSE_ASCODING_ERRORS(
- if (
m_display_list.get_character_by_name_i(std::string(name.c_str())) )
+ if ( m_display_list.get_character_by_name_i(name) )
{
log_warning("A sprite member (%s) clashes with "
"the name of an existing character "
@@ -1486,7 +1509,7 @@
// Try items on our display list.
- character* ch =
m_display_list.get_character_by_name_i(std::string(name.c_str()));
+ character* ch = m_display_list.get_character_by_name_i(name);
if (ch)
{
// Found object.
@@ -1495,7 +1518,7 @@
}
// Try textfield variables
- edit_text_character* etc = get_textfield_variable(name.c_str());
+ edit_text_character* etc = get_textfield_variable(name);
if ( etc )
{
val->set_string(etc->get_text_value());
Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- server/vm/ASHandlers.cpp 12 Jan 2007 12:03:41 -0000 1.27
+++ server/vm/ASHandlers.cpp 15 Jan 2007 00:06:59 -0000 1.28
@@ -16,7 +16,7 @@
//
-/* $Id: ASHandlers.cpp,v 1.27 2007/01/12 12:03:41 strk Exp $ */
+/* $Id: ASHandlers.cpp,v 1.28 2007/01/15 00:06:59 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -1858,7 +1858,8 @@
if ( target_name.empty() ) {
new_target = env.find_target(std::string("/"));
} else {
- new_target = env.find_target(target_name);
+ as_value target_val = env.get_variable(target_name);
+ new_target = target_val.to_sprite();
}
if (new_target == NULL)
Index: server/vm/ActionExec.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ActionExec.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- server/vm/ActionExec.cpp 12 Jan 2007 10:59:48 -0000 1.10
+++ server/vm/ActionExec.cpp 15 Jan 2007 00:06:59 -0000 1.11
@@ -16,7 +16,7 @@
//
-/* $Id: ActionExec.cpp,v 1.10 2007/01/12 10:59:48 strk Exp $ */
+/* $Id: ActionExec.cpp,v 1.11 2007/01/15 00:06:59 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -26,13 +26,14 @@
#include "action_buffer.h"
#include "swf_function.h"
#include "log.h"
-//#include "stream.h"
+#include "VM.h"
#include "swf.h"
#include "ASHandlers.h"
#include "as_environment.h"
#include <typeinfo>
+#include <boost/algorithm/string/case_conv.hpp>
#if !defined(_WIN32) && !defined(WIN32)
# include <pthread.h>
@@ -282,18 +283,46 @@
bool
ActionExec::delVariable(const std::string& name)
{
+ VM& vm = VM::get(); // cache this ?
+ if ( vm.getSWFVersion() < 7 )
+ {
+ std::string namei = name;
+ boost::to_lower(namei, vm.getLocale());
+ return env.del_variable_raw(namei, with_stack);
+ }
+ else
+ {
return env.del_variable_raw(name, with_stack);
+ }
}
void
ActionExec::setVariable(const std::string& name, const as_value& val)
{
+ VM& vm = VM::get(); // cache this ?
+ if ( vm.getSWFVersion() < 7 )
+ {
+ std::string namei = name;
+ boost::to_lower(namei, vm.getLocale());
+ return env.set_variable(namei, val, getWithStack());
+ }
+ else
+ {
return env.set_variable(name, val, getWithStack());
+ }
}
void
-ActionExec::setLocalVariable(const std::string& name, const as_value& val)
+ActionExec::setLocalVariable(const std::string& name_, const as_value& val)
{
+ VM& vm = VM::get(); // cache this ?
+
+ std::string name = name_;
+ if ( vm.getSWFVersion() < 7 )
+ {
+ boost::to_lower(name, vm.getLocale());
+ }
+
if ( isFunction() )
{
// TODO: set local in the function object?
@@ -310,14 +339,19 @@
as_value
ActionExec::getVariable(const std::string& name)
{
-#if 0
- if ( isFunction() && name == "super" )
+ VM& vm = VM::get();
+
+ if ( vm.getSWFVersion() < 7 )
{
- log_msg("Should return Base class of current function here...
");
- // this is likely NOT the constructor NOR the prototype
+ std::string namei = name;
+ boost::to_lower(namei, vm.getLocale());
+ return env.get_variable(namei, getWithStack());
}
-#endif
+ else
+ {
return env.get_variable(name, getWithStack());
+ }
+
}
} // end of namespace gnash
Index: server/vm/ActionExec.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ActionExec.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- server/vm/ActionExec.h 12 Jan 2007 10:59:48 -0000 1.6
+++ server/vm/ActionExec.h 15 Jan 2007 00:06:59 -0000 1.7
@@ -204,28 +204,38 @@
///
void skip_actions(size_t offset);
- /// \brief
- /// Delete named variable, seeking for
- /// it in the with stack if any
+ /// Delete named variable, seeking for it in the with stack if any
//
+ /// @param name
+ /// Name of the variable. Supports slash and dot syntax.
+ /// Name is converted to lowercase if SWF version is < 7.
+ ///
bool delVariable(const std::string& name);
- /// \brief
- /// Set a named variable, seeking for
- /// it in the with stack if any
+ /// Set a named variable, seeking for it in the with stack if any.
//
+ /// @param name
+ /// Name of the variable. Supports slash and dot syntax.
+ /// Name is converted to lowercase if SWF version is < 7.
+ ///
void setVariable(const std::string& name, const as_value& val);
/// \brief
/// If in a function context set a local variable,
/// otherwise, set a normal variable.
//
+ /// @param name
+ /// Name of the variable. Supports slash and dot syntax.
+ /// Name is converted to lowercase if SWF version is < 7.
+ ///
void setLocalVariable(const std::string& name, const as_value& val);
- /// \brief
- /// Get a named variable, seeking for
- /// it in the with stack if any
+ /// Get a named variable, seeking for it in the with stack if any.
//
+ /// @param name
+ /// Name of the variable. Supports slash and dot syntax.
+ /// Name is converted to lowercase if SWF version is < 7.
+ ///
as_value getVariable(const std::string& name);
/// Execute.
Index: testsuite/actionscript.all/getvariable.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/getvariable.as,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- testsuite/actionscript.all/getvariable.as 14 Jan 2007 17:39:06 -0000
1.4
+++ testsuite/actionscript.all/getvariable.as 15 Jan 2007 00:06:59 -0000
1.5
@@ -19,15 +19,18 @@
// compile this test case with Ming makeswf, and then
// execute it like this gnash -1 -r 0 -v out.swf
-rcsid="$Id: getvariable.as,v 1.4 2007/01/14 17:39:06 strk Exp $";
+rcsid="$Id: getvariable.as,v 1.5 2007/01/15 00:06:59 strk Exp $";
#include "check.as"
// see check.as
#ifdef MING_SUPPORTS_ASM
+_global.globalvar = "gv1";
+_global.globalobj = { m1: 1 };
+
//---------------------------------------------------------------------
-// Check 'var' access
+// Check access to root variable (simplest case)
//---------------------------------------------------------------------
var variable_in_root = 5;
@@ -40,18 +43,89 @@
check_equals(checkpoint, 5);
//---------------------------------------------------------------------
-// Check '../:var' access
-// (expected to fail)
+// Check access to root variable trough '_root.varname'
//---------------------------------------------------------------------
-var variable_in_root = 5;
+var variable_in_root = 5.1;
+asm {
+ push 'checkpoint'
+ push '_root.variable_in_root'
+ getvariable
+ setvariable
+};
+check_equals(checkpoint, 5.1);
+
+//---------------------------------------------------------------------
+// Check access to root variable trough '_level0.varname'
+//---------------------------------------------------------------------
+
+var variable_in_root = 5.2;
+asm {
+ push 'checkpoint'
+ push '_level0.variable_in_root'
+ getvariable
+ setvariable
+};
+check_equals(checkpoint, 5.2);
+
+//---------------------------------------------------------------------
+// Check access to root variable trough 'this.varname'
+//---------------------------------------------------------------------
+
+var variable_in_root = 5.3;
+asm {
+ push 'checkpoint'
+ push 'this.variable_in_root'
+ getvariable
+ setvariable
+};
+check_equals(checkpoint, 5.3);
+
+//---------------------------------------------------------------------
+// Check access to root variable trough 'this._root._level0.varname'
+// (insane)
+//---------------------------------------------------------------------
+
+var variable_in_root = 5.4;
+asm {
+ push 'checkpoint'
+ push 'this._root._level0.variable_in_root'
+ getvariable
+ setvariable
+};
+check_equals(checkpoint, 5.4);
+
+//---------------------------------------------------------------------
+// Check access to root variable trough 'THIS.varname'
+//---------------------------------------------------------------------
+
+var variable_in_root = 5.5;
+asm {
+ push 'checkpoint'
+ push 'THIS.variable_in_root'
+ getvariable
+ setvariable
+};
+#if OUTPUT_VERSION > 6
+check_equals(checkpoint, undefined);
+#else
+check_equals(checkpoint, 5.5);
+#endif
+
+
+//---------------------------------------------------------------------
+// Check '../:variable_in_root' access
+// (expected to fail, but I'm not sure why)
+//---------------------------------------------------------------------
+
+var variable_in_root = 6;
asm {
push 'checkpoint'
push '../:variable_in_root'
getvariable
setvariable
};
-xcheck_equals(checkpoint, undefined);
+check_equals(checkpoint, undefined);
//---------------------------------------------------------------------
// Check '../invalidname' access
@@ -67,7 +141,23 @@
getvariable
setvariable
};
-xcheck_equals(checkpoint, undefined);
+check_equals(checkpoint, undefined);
+
+//---------------------------------------------------------------------
+// Check '/invalidname2' access
+// (expected to fail)
+//---------------------------------------------------------------------
+
+asm {
+ push '/invalidname2'
+ push '18'
+ setvariable
+ push 'checkpoint'
+ push '/invalidname'
+ getvariable
+ setvariable
+};
+check_equals(checkpoint, undefined);
//---------------------------------------------------------------------
// Check 'obj.member' access
@@ -80,7 +170,36 @@
getvariable
setvariable
};
-xcheck_equals(objmemb, 3);
+check_equals(objmemb, 3);
+
+//---------------------------------------------------------------------
+// Check 'obj._root.variable_in_root' access
+// (expect to fail)
+//---------------------------------------------------------------------
+
+var variable_in_root = 10.0;
+var o = { memb:4 };
+asm {
+ push 'checkpoint'
+ push 'o._root.variable_in_root'
+ getvariable
+ setvariable
+};
+check_equals(checkpoint, undefined);
+
+//---------------------------------------------------------------------
+// Check 'obj.this.memb' access
+// (expect to fail)
+//---------------------------------------------------------------------
+
+var o = { memb:10.1 };
+asm {
+ push 'checkpoint'
+ push 'o.this.memb'
+ getvariable
+ setvariable
+};
+check_equals(checkpoint, undefined);
//---------------------------------------------------------------------
// Check 'obj1.obj2.member' access
@@ -94,7 +213,39 @@
getvariable
setvariable
};
-xcheck_equals(checkpoint, 4);
+check_equals(checkpoint, 4);
+
+//---------------------------------------------------------------------
+// Check 'obj1.globalvar'
+// (expect to fail)
+//---------------------------------------------------------------------
+
+var o3 = { memb:4 };
+asm {
+ push 'checkpoint'
+ push 'o3.globalvar'
+ getvariable
+ setvariable
+};
+check_equals(checkpoint, undefined);
+
+//---------------------------------------------------------------------
+// Check 'globalobj.m1'
+//---------------------------------------------------------------------
+
+var o3 = { memb:4 };
+asm {
+ push 'checkpoint'
+ push 'globalobj.m1'
+ getvariable
+ setvariable
+};
+#if OUTPUT_VERSION > 5
+check_equals(checkpoint, 1);
+#else // OUTPUT_VERSION < 6
+// _global was added in SWF6 !
+xcheck_equals(checkpoint, undefined);
+#endif
//-----------------------------------------------------------------------
// Check 'obj/:member' access
@@ -107,7 +258,7 @@
getvariable
setvariable
};
-xcheck_equals(objmemb, 3);
+check_equals(objmemb, 3);
//-----------------------------------------------------------------------
// Check 'invalid/name' access
- [Gnash-commit] gnash ChangeLog server/as_environment.cpp serve...,
Sandro Santilli <=