[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 14:16:06 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 07/01/15 14:16:06
Modified files:
. : ChangeLog
server : as_environment.cpp as_environment.h
server/vm : ASHandlers.cpp ASHandlers.h ActionExec.cpp
ActionExec.h
testsuite/actionscript.all: Makefile.am
Added files:
testsuite/actionscript.all: swap.as
Log message:
2007-01-15 Sandro Santilli <address@hidden>
* server/as_environment.{cpp,h}: added padStack
method to help stack underrun fixes.
* server/vm/: ASHandlers.{cpp,h}, ActionExec.{cpp,h}:
Moved stack underrun handling from ASHandlers to
ActionExec, taking "stack frame" in consideration.
The fix for stack underron will now insert undefined
variables in *front* of the stack frame, not at the
end. The effect is that *final* arguments of tags are
undefined, not *initial*.
* testsuite/actionscript.all/Makefile.am:
Enabled build of swap.as testcase.
Contribution by Zou Lunkai:
* testsuite/actionscript.all/swap.as: new test for
stack underrun handling.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2106&r2=1.2107
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.cpp?cvsroot=gnash&r1=1.53&r2=1.54
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_environment.h?cvsroot=gnash&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.h?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ActionExec.cpp?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ActionExec.h?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Makefile.am?cvsroot=gnash&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/swap.as?cvsroot=gnash&rev=1.1
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2106
retrieving revision 1.2107
diff -u -b -r1.2106 -r1.2107
--- ChangeLog 15 Jan 2007 00:06:58 -0000 1.2106
+++ ChangeLog 15 Jan 2007 14:16:06 -0000 1.2107
@@ -1,3 +1,22 @@
+2007-01-15 Sandro Santilli <address@hidden>
+
+ * server/as_environment.{cpp,h}: added padStack
+ method to help stack underrun fixes.
+ * server/vm/: ASHandlers.{cpp,h}, ActionExec.{cpp,h}:
+ Moved stack underrun handling from ASHandlers to
+ ActionExec, taking "stack frame" in consideration.
+ The fix for stack underron will now insert undefined
+ variables in *front* of the stack frame, not at the
+ end. The effect is that *final* arguments of tags are
+ undefined, not *initial*.
+ * testsuite/actionscript.all/Makefile.am:
+ Enabled build of swap.as testcase.
+
+2007-01-15 Zou Lunkai <address@hidden>
+
+ * testsuite/actionscript.all/swap.as: new test for
+ stack underrun handling.
+
2007-01-14 Sandro Santilli <address@hidden>
* server/vm/ActionExec.{cpp,h} (getVariable, setVariable,
Index: server/as_environment.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.cpp,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- server/as_environment.cpp 15 Jan 2007 00:06:59 -0000 1.53
+++ server/as_environment.cpp 15 Jan 2007 14:16:06 -0000 1.54
@@ -16,7 +16,7 @@
//
-/* $Id: as_environment.cpp,v 1.53 2007/01/15 00:06:59 strk Exp $ */
+/* $Id: as_environment.cpp,v 1.54 2007/01/15 14:16:06 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -916,8 +916,16 @@
return endLocal();
}
+void
+as_environment::padStack(size_t offset, size_t count)
+{
+ assert( offset <= m_stack.size() );
+ m_stack.insert(m_stack.begin()+offset, count, as_value());
}
+} // end of gnash namespace
+
+
// Local Variables:
// mode: C++
Index: server/as_environment.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_environment.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- server/as_environment.h 15 Jan 2007 00:06:59 -0000 1.38
+++ server/as_environment.h 15 Jan 2007 14:16:06 -0000 1.39
@@ -18,7 +18,7 @@
//
//
-/* $Id: as_environment.h,v 1.38 2007/01/15 00:06:59 strk Exp $ */
+/* $Id: as_environment.h,v 1.39 2007/01/15 14:16:06 strk Exp $ */
#ifndef GNASH_AS_ENVIRONMENT_H
#define GNASH_AS_ENVIRONMENT_H
@@ -80,7 +80,8 @@
character* get_target() { return m_target; }
void set_target(character* target) { m_target = target; }
- // stack access/manipulation
+ /// @{ Stack access/manipulation
+
// @@ TODO do more checking on these
template<class T>
// stack access/manipulation
@@ -124,6 +125,13 @@
m_stack.resize(m_stack.size() - count);
}
+ /// Insert 'count' undefined values before 'offset'.
+ //
+ /// An offset of 0 will prepend the values,
+ /// An offset of size() [too far] will append the values.
+ ///
+ void padStack(size_t offset, size_t count);
+
/// Returns index of top stack element
// FIXME: what if stack is empty ??
// I'd obsolete this and convert calling code to use
@@ -132,6 +140,9 @@
size_t stack_size() const { return m_stack.size(); }
+ /// @} stack access/manipulation
+ ///
+
/// \brief
/// Return the (possibly UNDEFINED) value of the named variable
//
Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- server/vm/ASHandlers.cpp 15 Jan 2007 00:06:59 -0000 1.28
+++ server/vm/ASHandlers.cpp 15 Jan 2007 14:16:06 -0000 1.29
@@ -16,7 +16,7 @@
//
-/* $Id: ASHandlers.cpp,v 1.28 2007/01/15 00:06:59 strk Exp $ */
+/* $Id: ASHandlers.cpp,v 1.29 2007/01/15 14:16:06 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -765,7 +765,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1) += env.top(0);
env.drop(1);
}
@@ -775,7 +775,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1) -= env.top(0);
env.drop(1);
}
@@ -785,7 +785,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1) *= env.top(0);
env.drop(1);
}
@@ -795,7 +795,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1) /= env.top(0);
env.drop(1);
}
@@ -808,7 +808,7 @@
assert(thread.code[thread.pc] == SWF::ACTION_EQUAL); // 0x0E
- ensure_stack(env, 2);
+ thread.ensureStack(2);
as_value& op1 = env.top(0);
as_value& op2 = env.top(1);
@@ -828,7 +828,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).set_bool(env.top(1) < env.top(0));
env.drop(1);
}
@@ -838,7 +838,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).set_bool(env.top(1).to_bool() && env.top(0).to_bool());
env.drop(1);
}
@@ -848,7 +848,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).set_bool(env.top(1).to_bool() || env.top(0).to_bool());
env.drop(1);
}
@@ -858,7 +858,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.top(0).set_bool(! env.top(0).to_bool());
}
@@ -867,7 +867,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).set_bool(env.top(1).to_tu_string() ==
env.top(0).to_tu_string());
env.drop(1);
}
@@ -877,7 +877,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
int version = env.get_version();
env.top(0).set_int(env.top(0).to_tu_string_versioned(version).utf8_length());
}
@@ -887,7 +887,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 3); // size, base, string
+ thread.ensureStack(3); // size, base, string
as_value& size_val = env.top(0);
as_value& base_val = env.top(1);
@@ -979,7 +979,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
// this is an overhead only if SWF is malformed.
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.drop(1);
}
@@ -988,7 +988,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.top(0).set_int(int(floor(env.top(0).to_number())));
}
@@ -998,7 +998,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1); // variable name
+ thread.ensureStack(1); // variable name
as_value& top_value = env.top(0);
const char* ptr = top_value.to_string();
@@ -1035,7 +1035,7 @@
as_environment& env = thread.env;
// stack must be contain at least two items
- ensure_stack(env, 2);
+ thread.ensureStack(2);
assert(env.top(1).to_string());
thread.setVariable(env.top(1).to_std_string(), env.top(0));
@@ -1055,7 +1055,7 @@
as_environment& env = thread.env;
- ensure_stack(env, 1); // target name
+ thread.ensureStack(1); // target name
//Vitaly: env.drop(1) remove object on which refers const char *
target_name
//strk: shouldn't we use env.pop() instead ? No (see above comment)
@@ -1073,7 +1073,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // two strings
+ thread.ensureStack(2); // two strings
int version = env.get_version();
env.top(1).convert_to_string_versioned(version);
@@ -1087,7 +1087,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // prop num, target
+ thread.ensureStack(2); // prop num, target
as_value& tgt_val = env.top(1);
character *target = env.find_target(tgt_val);
@@ -1126,7 +1126,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 3); // prop val, prop num, target
+ thread.ensureStack(3); // prop val, prop num, target
character *target = env.find_target(env.top(2));
unsigned int prop_number = (unsigned int)env.top(1).to_number();
@@ -1153,7 +1153,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 3);
+ thread.ensureStack(3);
sprite_instance* si = env.get_target()->to_movie();
if ( ! si )
@@ -1176,7 +1176,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
sprite_instance* tgt = env.get_target()->to_movie();
assert(tgt);
@@ -1193,7 +1193,7 @@
//// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
// strk: why not using pop() ?
dbglogfile << env.top(0).to_string() << endl;
@@ -1208,7 +1208,7 @@
assert(thread.code[thread.pc] == SWF::ACTION_STARTDRAGMOVIE);
- ensure_stack(env, 3);
+ thread.ensureStack(3);
drag_state st;
@@ -1226,7 +1226,7 @@
// 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
- ensure_stack(env, 7); // original 3 + 4 for bound
+ thread.ensureStack(7); // original 3 + 4 for bound
// It looks like coordinates of drag bounds are
// given as PIXELS :
@@ -1283,7 +1283,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).set_bool(env.top(1).to_tu_string() < env.top(0).to_tu_string());
}
@@ -1302,7 +1302,7 @@
as_environment& env = thread.env;
- ensure_stack(env, 2); // super, instance
+ thread.ensureStack(2); // super, instance
// Get the "super" function
as_function* super = env.top(0).to_as_function();
@@ -1352,7 +1352,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1); // max
+ thread.ensureStack(1); // max
int max = int(env.top(0).to_number());
if (max < 1) max = 1;
@@ -1372,7 +1372,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.top(0).set_int(env.top(0).to_string()[0]);
}
@@ -1381,7 +1381,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
char buf[2];
buf[0] = int(env.top(0).to_number());
buf[1] = 0;
@@ -1438,7 +1438,7 @@
as_environment& env = thread.env;
const action_buffer& code = thread.code;
- ensure_stack(env, 1); // expression
+ thread.ensureStack(1); // expression
// how many actions to skip if frame has not been loaded
uint8 skip = code[thread.pc+3];
@@ -1526,7 +1526,7 @@
size_t i = pc;
size_t count = 0;
while (i - pc < static_cast<size_t>(length)) {
- int id; // for dict (constant pool) lookup
+ int id=0; // for dict (constant pool) lookup
// declared here because also used
// by verbose action output
uint8_t type = code[3 + i];
@@ -1883,7 +1883,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // target, url
+ thread.ensureStack(2); // target, url
const action_buffer& code = thread.code;
@@ -1919,7 +1919,7 @@
assert( code[pc] == SWF::ACTION_BRANCHIFTRUE );
- ensure_stack(env, 1); // bool
+ thread.ensureStack(1); // bool
int16_t offset = code.read_int16(pc+3);
@@ -1943,7 +1943,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1); // frame spec
+ thread.ensureStack(1); // frame spec
// Note: no extra data in this instruction!
sprite_instance* tgt = env.get_target()->to_movie();
@@ -1959,7 +1959,7 @@
as_environment& env = thread.env;
- ensure_stack(env, 1); // expression
+ thread.ensureStack(1); // expression
const action_buffer& code = thread.code;
size_t pc = thread.pc;
@@ -2114,7 +2114,7 @@
assert(thread.code[thread.pc] == SWF::ACTION_DELETE2); // 0x3B
- ensure_stack(env, 1); // var
+ thread.ensureStack(1); // var
// See bug #18482, this works fine now (assuming the bug report is
correct)
env.top(0) = thread.delVariable(env.top(0).to_std_string());
@@ -2125,7 +2125,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // value, var
+ thread.ensureStack(2); // value, var
as_value value = env.pop();
as_value varname = env.pop();
@@ -2138,7 +2138,7 @@
//GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // func name, nargs
+ thread.ensureStack(2); // func name, nargs
//cerr << "At ActionCallFunction enter:"<<endl;
//env.dump_stack();
@@ -2161,7 +2161,7 @@
}
int nargs = (int)env.top(1).to_number();
- ensure_stack(env, 2+nargs); // func name, nargs, args
+ thread.ensureStack(2+nargs); // func name, nargs, args
//log_msg("Function's nargs: %d", nargs);
@@ -2187,7 +2187,7 @@
//log_msg("Before top/drop (retval=%p)", (void*)retval);
//env.dump_stack();
- ensure_stack(env, 1); // ret value
+ thread.ensureStack(1); // ret value
// Put top of stack in the provided return slot, if
// it's not NULL.
@@ -2210,7 +2210,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // x, ,y
+ thread.ensureStack(2); // x, ,y
as_value result;
double y = env.pop().to_number();
@@ -2230,7 +2230,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // classname, nargs
+ thread.ensureStack(2); // classname, nargs
as_value val = env.pop();
std::string classname;
@@ -2243,7 +2243,7 @@
int nargs = (int) env.pop().to_number();
- ensure_stack(env, nargs); // previous 2 entries popped
+ thread.ensureStack(nargs); // previous 2 entries popped
as_value constructor = thread.getVariable(classname);
@@ -2260,7 +2260,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1); // var name
+ thread.ensureStack(1); // var name
std::string varname = env.top(0).to_std_string();
env.declare_local(varname);
env.drop(1);
@@ -2272,12 +2272,12 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1); // array size name
+ thread.ensureStack(1); // array size name
int array_size = (int) env.pop().to_number();
assert(array_size >= 0);
- ensure_stack(env, (unsigned int)array_size); // array elements
+ thread.ensureStack((unsigned int)array_size); // array elements
//log_msg("xxx init array: size = %d, top of stack = %d", array_size,
env.get_top_index());//xxxxx
@@ -2310,7 +2310,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1); // nmembers
+ thread.ensureStack(1); // nmembers
//
// SWFACTION_PUSH
@@ -2322,7 +2322,7 @@
int nmembers = (int) env.pop().to_number();
- ensure_stack(env, nmembers); // members
+ thread.ensureStack(nmembers); // members
boost::intrusive_ptr<as_object>
new_obj_ptr(init_object_instance().release());
@@ -2350,7 +2350,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.top(0).set_string(env.top(0).typeOf());
}
@@ -2381,7 +2381,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1); // var_name
+ thread.ensureStack(1); // var_name
// Get the object
as_value& var_name = env.top(0);
@@ -2414,7 +2414,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
int version = env.get_version();
if (env.top(0).is_string() || env.top(1).is_string() )
@@ -2435,7 +2435,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
if ( env.top(1).is_string() ) {
env.top(1).set_bool(env.top(1).to_tu_string() <
env.top(0).to_tu_string());
@@ -2453,7 +2453,7 @@
assert(thread.code[thread.pc] == SWF::ACTION_NEWEQUALS);
- ensure_stack(env, 2);
+ thread.ensureStack(2);
/// ECMA-262 abstract equality comparison (sect 11.9.3)
env.top(1).set_bool(env.top(1) == env.top(0));
@@ -2465,7 +2465,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.top(0).convert_to_number();
}
@@ -2474,7 +2474,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
int version = env.get_version();
env.top(0).convert_to_string_versioned(version);
}
@@ -2484,7 +2484,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.push(env.top(0));
}
@@ -2493,7 +2493,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
as_value temp = env.top(1);
env.top(1) = env.top(0);
env.top(0) = temp;
@@ -2505,7 +2505,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // member name, target
+ thread.ensureStack(2); // member name, target
// Some corner case behaviors depend on the SWF file version.
int version = env.get_version();
@@ -2554,7 +2554,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 3); // value, member, object
+ thread.ensureStack(3); // value, member, object
as_object* obj = env.top(2).to_object();
@@ -2590,7 +2590,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.top(0) += 1;
}
@@ -2600,7 +2600,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
env.top(0) -= 1;
}
@@ -2610,7 +2610,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 3); // method_name, obj, nargs
+ thread.ensureStack(3); // method_name, obj, nargs
as_value result;
@@ -2627,7 +2627,7 @@
// Get number of arguments
int nargs = static_cast<int>(env.top(2).to_number());
- ensure_stack(env, 3+nargs); // actual args
+ thread.ensureStack(3+nargs); // actual args
IF_VERBOSE_ACTION (
log_action(" method name: %s", method_name.c_str());
@@ -2692,13 +2692,13 @@
assert( thread.code[thread.pc] == SWF::ACTION_NEWMETHOD );
- ensure_stack(env, 3); // method, object, nargs
+ thread.ensureStack(3); // method, object, nargs
as_value method_name = env.pop().to_string();
as_value obj_val = env.pop();
int nargs = (int)env.pop().to_number();
- ensure_stack(env, nargs); // previous 3 entries popped
+ thread.ensureStack(nargs); // previous 3 entries popped
as_object* obj = obj_val.to_object();
if ( ! obj )
@@ -2742,7 +2742,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // super, instance
+ thread.ensureStack(2); // super, instance
// Get the "super" function
as_function* super = env.top(0).to_as_function();
@@ -2774,7 +2774,7 @@
as_environment& env = thread.env;
- ensure_stack(env, 1); // object
+ thread.ensureStack(1); // object
// Get the object.
// Copy it so we can override env.top(0)
@@ -2803,7 +2803,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1) &= env.top(0);
env.drop(1);
}
@@ -2813,7 +2813,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1) |= env.top(0);
env.drop(1);
}
@@ -2823,7 +2823,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1) ^= env.top(0);
env.drop(1);
}
@@ -2833,7 +2833,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).asr(env.top(0));
env.drop(1);
}
@@ -2843,7 +2843,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).lsr(env.top(0));
env.drop(1);
}
@@ -2853,7 +2853,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).lsr(env.top(0));
env.drop(1);
}
@@ -2863,7 +2863,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).set_bool(env.top(1).strictly_equals(env.top(0)));
env.drop(1);
}
@@ -2873,7 +2873,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
if (env.top(1).is_string()) {
env.top(1).set_bool(env.top(1).to_tu_string() >
env.top(0).to_tu_string());
} else {
@@ -2887,7 +2887,7 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2);
+ thread.ensureStack(2);
env.top(1).set_bool(env.top(1).to_tu_string() > env.top(0).to_tu_string());
env.drop(1);
}
@@ -2898,7 +2898,7 @@
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- ensure_stack(env, 2); // super, sub
+ thread.ensureStack(2); // super, sub
as_function* super = env.top(0).to_as_function();
as_function* sub = env.top(1).to_as_function();
@@ -3052,7 +3052,7 @@
assert( code[pc] == SWF::ACTION_WITH );
- ensure_stack(env, 1); // the object
+ thread.ensureStack(1); // the object
as_object* with_obj = env.pop().to_object();
const std::vector<with_stack_entry>& with_stack = thread.getWithStack();
@@ -3173,7 +3173,7 @@
as_environment& env = thread.env;
- ensure_stack(env, 1);
+ thread.ensureStack(1);
const action_buffer& code = thread.code;
@@ -3223,24 +3223,6 @@
}
}
-/*static private*/
-void
-SWFHandlers::fix_stack_underrun(as_environment& env, size_t required)
-{
- assert ( env.stack_size() < required );
-
- size_t missing = required-env.stack_size();
-
- log_error("Stack underrun: " SIZET_FMT " elements required, " SIZET_FMT
- " available. Fixing by pushing " SIZET_FMT " undefined values on the"
- " missing slots.", required, env.stack_size(), missing);
-
- for (size_t i=0; i<missing; ++i)
- {
- env.push(as_value());
- }
-}
-
} // namespace gnash::SWF
} // namespace gnash
Index: server/vm/ASHandlers.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/vm/ASHandlers.h 13 Dec 2006 11:08:10 -0000 1.4
+++ server/vm/ASHandlers.h 15 Jan 2007 14:16:06 -0000 1.5
@@ -23,7 +23,6 @@
#include <map>
#include <vector>
#include "action.h" // we should get rid of this probably
-#include "as_environment.h" // for ensure_stack inline (must be inlined!)
#include "swf.h"
@@ -125,23 +124,6 @@
static container_type & get_handlers();
static std::vector<std::string> & get_property_names();
- // Ensure the stack has at least 'required' elements, fixing
- // it if required.
- // This is an inline to it can eventually be made a no-op
- // when gnash works and input SWFs are known to be valid.
- static void ensure_stack(as_environment& env, size_t required)
- {
- if ( env.stack_size() < required )
- {
- fix_stack_underrun(env, required);
- }
- }
-
- // Fill all the slots to reach the 'required' stack size
- // with undefined values. This method should *only* be
- // called by ensure_stack() above.
- static void fix_stack_underrun(as_environment& env, size_t required);
-
/// Common code for ActionGetUrl and ActionGetUrl2
//
/// @see http://sswf.sourceforge.net/SWFalexref.html#action_get_url2
Index: server/vm/ActionExec.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ActionExec.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- server/vm/ActionExec.cpp 15 Jan 2007 00:06:59 -0000 1.11
+++ server/vm/ActionExec.cpp 15 Jan 2007 14:16:06 -0000 1.12
@@ -16,7 +16,7 @@
//
-/* $Id: ActionExec.cpp,v 1.11 2007/01/15 00:06:59 strk Exp $ */
+/* $Id: ActionExec.cpp,v 1.12 2007/01/15 14:16:06 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -122,7 +122,7 @@
character* original_target = env.get_target();
- size_t original_stack_size = env.stack_size();
+ _initial_stack_size = env.stack_size();
#if DEBUG_STACK
IF_VERBOSE_ACTION (
@@ -198,24 +198,24 @@
env.set_target(original_target);
// check if the stack was smashed
- if ( original_stack_size > env.stack_size() )
+ if ( _initial_stack_size > env.stack_size() )
{
log_warning("Stack smashed (ActionScript compiler bug?)."
"Fixing by pushing undefined values to the missing slots, "
" but don't expect things to work afterwards.");
- size_t missing = original_stack_size - env.stack_size();
+ size_t missing = _initial_stack_size - env.stack_size();
for (size_t i=0; i<missing; ++i)
{
env.push(as_value());
}
}
- else if ( original_stack_size < env.stack_size() )
+ else if ( _initial_stack_size < env.stack_size() )
{
// We can argue this would be an "size-optimized" SWF instead...
IF_VERBOSE_MALFORMED_SWF(
log_warning("Elements left on the stack after block execution.
Cleaning up.");
);
- env.drop(env.stack_size()-original_stack_size);
+ env.drop(env.stack_size()-_initial_stack_size);
}
}
@@ -354,6 +354,25 @@
}
+/*private*/
+void
+ActionExec::fixStackUnderrun(size_t required)
+{
+ size_t slots_left = env.stack_size() - _initial_stack_size;
+ size_t missing = required-slots_left;
+
+ //IF_VERBOSE_ASCODING_ERRORS(
+ log_warning("Stack underrun: " SIZET_FMT " elements required, "
+ SIZET_FMT "/" SIZET_FMT " available. "
+ "Fixing by pushing " SIZET_FMT " undefined values on the"
+ " missing slots.",
+ required, _initial_stack_size, env.stack_size(),
+ missing);
+ //);
+
+ env.padStack(_initial_stack_size, missing);
+}
+
} // end of namespace gnash
Index: server/vm/ActionExec.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ActionExec.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- server/vm/ActionExec.h 15 Jan 2007 00:06:59 -0000 1.7
+++ server/vm/ActionExec.h 15 Jan 2007 14:16:06 -0000 1.8
@@ -24,13 +24,13 @@
#endif
#include "with_stack_entry.h"
+#include "as_environment.h" // for ensureStack
#include <vector>
// Forward declarations
namespace gnash {
class action_buffer;
- class as_environment;
class as_value;
class swf_function;
}
@@ -40,6 +40,8 @@
/// Executor of an action_buffer
class ActionExec {
+private:
+
/// the 'with' stack associated with this execution thread
std::vector<with_stack_entry> with_stack;
@@ -72,8 +74,41 @@
///
const swf_function* _func;
+ size_t _initial_stack_size;
+
+ /// Warn about a stack underrun and fix it
+ //
+ /// The fix is padding the stack with undefined
+ /// values for the missing slots.
+ ///
+ /// @param required
+ /// Number of items required.
+ ///
+ void ActionExec::fixStackUnderrun(size_t required);
+
public:
+ /// \brief
+ /// Ensure the current stack frame has at least 'required' elements,
+ /// fixing it if required.
+ //
+ /// Underruns are fixed by inserting elements at the start of
+ /// stack frame, so that undefined function arguments are the
+ /// *last* ones in the list.
+ ///
+ void ensureStack(size_t required)
+ {
+ // The stack_size() < _initial_stack_size case should
+ // be handled this by stack smashing checks
+ assert( env.stack_size() >= _initial_stack_size );
+
+ size_t slots_left = env.stack_size() - _initial_stack_size;
+ if ( slots_left < required )
+ {
+ fixStackUnderrun(required);
+ }
+ }
+
/// The actual action buffer
//
/// TODO: provide a getter and make private
Index: testsuite/actionscript.all/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Makefile.am,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- testsuite/actionscript.all/Makefile.am 13 Jan 2007 23:35:56 -0000
1.62
+++ testsuite/actionscript.all/Makefile.am 15 Jan 2007 14:16:06 -0000
1.63
@@ -16,7 +16,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-# $Id: Makefile.am,v 1.62 2007/01/13 23:35:56 strk Exp $
+# $Id: Makefile.am,v 1.63 2007/01/15 14:16:06 strk Exp $
AUTOMAKE_OPTIONS = dejagnu
@@ -71,6 +71,7 @@
array.as \
delete.as \
getvariable.as \
+ swap.as \
Boolean.as \
Camera.as \
Color.as \
Index: testsuite/actionscript.all/swap.as
===================================================================
RCS file: testsuite/actionscript.all/swap.as
diff -N testsuite/actionscript.all/swap.as
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/actionscript.all/swap.as 15 Jan 2007 14:16:06 -0000 1.1
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modchecky
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; check not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fcheckth Floor, Boston, MA 02110-1301
USA
+//
+
+/*
+ * Zou Lunkai, address@hidden
+ * Test stack status after action "Swap"
+ */
+
+rcsid="$Id: swap.as,v 1.1 2007/01/15 14:16:06 strk Exp $";
+
+#include "check.as"
+
+// see check.as
+#ifdef MING_SUPPORTS_ASM
+
+var var_x = "init_x";
+
+//stack:
+asm
+{
+ push "var_x" //stack: "var_x"
+ swap //stack: "var_x" undefined
+ pop //stack: "var_x"
+ push "hello" //stack: "var_x" "hello"
+ setvariable //stack:
+};
+check_equals(var_x, "hello");
+
+#endif
+