[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/ActionExec.cpp server/sw...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/ActionExec.cpp server/sw... |
Date: |
Tue, 27 Jun 2006 18:45:26 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 06/06/27 18:45:26
Modified files:
. : ChangeLog
server : ActionExec.cpp
server/swf : ASHandlers.cpp
Log message:
* server/swf/ASHandlers.cpp, server/ActionExec.cpp: moved
all known action handlers implementations from ActionExec
to ASHandlers, general cleanups.
* server/swf/ASHandlers.cpp: fixed bug in ActionDefineFunction2.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.433&r2=1.434
http://cvs.savannah.gnu.org/viewcvs/gnash/server/ActionExec.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/ASHandlers.cpp?cvsroot=gnash&r1=1.14&r2=1.15
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.433
retrieving revision 1.434
diff -u -b -r1.433 -r1.434
--- ChangeLog 26 Jun 2006 10:12:10 -0000 1.433
+++ ChangeLog 27 Jun 2006 18:45:26 -0000 1.434
@@ -1,3 +1,10 @@
+2006-06-27 Sandro Santilli <address@hidden>
+
+ * server/swf/ASHandlers.cpp, server/ActionExec.cpp: moved
+ all known action handlers implementations from ActionExec
+ to ASHandlers, general cleanups.
+ * server/swf/ASHandlers.cpp: fixed bug in ActionDefineFunction2.
+
2006-06-26 Sandro Santilli <address@hidden>
* server/Function.h, server/Function.cpp: added assertion checking
Index: server/ActionExec.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/ActionExec.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/ActionExec.cpp 26 Jun 2006 10:12:10 -0000 1.3
+++ server/ActionExec.cpp 27 Jun 2006 18:45:26 -0000 1.4
@@ -74,24 +74,6 @@
s_fscommand_handler = handler;
}
-// Utility. Try to convert str to a number. If successful,
-// put the result in *result, and return true. If not
-// successful, put 0 in *result, and return false.
-static bool string_to_number(double* result, const char* str)
-{
- char* tail = 0;
- *result = strtod(str, &tail);
- if (tail == str || *tail != 0)
- {
- // Failed conversion to Number.
- return false;
- }
- return true;
-}
-
-
-
-
ActionExec::ActionExec(const action_buffer& abuf, as_environment& newEnv,
size_t nStartPC, size_t exec_bytes, as_value* retval,
const std::vector<with_stack_entry>& initial_with_stack,
@@ -166,6 +148,7 @@
next_pc = pc + length + 3;
}
+ // Do we still need this ?
if ( action_id == SWF::ACTION_END ) {
// this would turn into an assertion (next_pc==stop_pc)
log_msg("At ACTION_END next_pc=%d, stop_pc=%d", next_pc,
stop_pc);
@@ -177,444 +160,6 @@
// Control flow actions will change the PC (next_pc)
pc = next_pc;
-//
-// The following handlers implementations must be moved
-// to swf/ASHandlers. Are kept for reference
-//
-#if 0 // {
- if ( ! ash.execute((action_type)action_id, *this) )
- {
- // Action handler not yet ported to new layout
-
-#if 0
- switch (action_id) {
-
- case SWF::ACTION_GOTOFRAME: // goto frame
- {
- int frame = code.read_int16(pc+3);
- // 0-based already?
- //// Convert from 1-based to 0-based
- //frame--;
- env.get_target()->goto_frame(frame);
- break;
- }
-
-#if 0
- case SWF::ACTION_GETURL: // get url
- {
- // If this is an FSCommand, then call the callback
- // handler, if any.
-
- // Two strings as args.
- const char* url = code.read_string(pc+3);
- size_t url_len = strlen(url);
- const char* target = code.read_string(pc+3+url_len+1);
-
- // If the url starts with an "http" or "https",
- // then we want to load it into a web browser.
- if (strncmp(url, "http", 4) == 0) {
-// if (windowid) {
-// Atom mAtom = 486;
-// Display *mDisplay = XOpenDisplay(NULL);
-// XLockDisplay(mDisplay);
-// XChangeProperty (mDisplay, windowid,
mAtom,
-// XA_STRING, 8,
PropModeReplace,
-// (unsigned char *)url,
-// url_len);
-
-// XUnlockDisplay(mDisplay);
-// XCloseDisplay(mDisplay);
-// } else {
- string command = "firefox -remote \"openurl(";
- command += url;
- command += ")\"";
- dbglogfile << "Launching URL... " << command << endl;
-// movie *target = env.get_target();
-// target->get_url(url);
- system(command.c_str());
-// }
- break;
- }
-
- // If the url starts with "FSCommand:", then this is
- // a message for the host app.
- if (strncmp(url, "FSCommand:", 10) == 0) {
- if (s_fscommand_handler) {
- // Call into the app.
-
(*s_fscommand_handler)(env.get_target()->get_root_interface(), url + 10,
target);
- }
- } else {
-#ifdef EXTERN_MOVIE
-// log_error("get url: target=%s, url=%s\n",
target, url);
-
- tu_string tu_target = target;
- movie* target_movie = env.find_target(tu_target);
- if (target_movie != NULL) {
- movie *root_movie =
env.get_target()->get_root_movie();
- attach_extern_movie(url, target_movie, root_movie);
- } else {
- log_error("get url: target %s not found\n", target);
- }
-#endif // EXTERN_MOVIE
- }
-
- break;
- }
-#endif
-
- case SWF::ACTION_SETREGISTER: // store_register
- {
- int reg = code[pc + 3];
- // Save top of stack in specified register.
- if ( isFunction2() ) {
- *(env.local_register_ptr(reg)) = env.top(0);
-
- log_action("-------------- local register[%d] =
'%s'\n",
- reg,
- env.top(0).to_string());
- } else if (reg >= 0 && reg < 4) {
- env.m_global_register[reg] = env.top(0);
-
- log_action("-------------- global register[%d] =
'%s'\n",
- reg,
- env.top(0).to_string());
- } else {
- log_error("store_register[%d] -- register out of
bounds!", reg);
- }
-
- break;
- }
-
-#if 0
- case SWF::ACTION_CONSTANTPOOL: // decl_dict: declare dictionary
- {
- //int i = pc;
- //int count = code[pc + 3] | (code[pc + 4] << 8);
- //i += 2;
-
- code.process_decl_dict(pc, next_pc);
-
- break;
- }
-#endif
-
-#if 0
- case SWF::ACTION_WAITFORFRAME: // wait for frame
- {
- // If we haven't loaded a specified frame yet, then we're
supposed to skip
- // some specified number of actions.
- //
- // Since we don't load incrementally, just ignore this opcode.
- break;
- }
-#endif
-
- case SWF::ACTION_SETTARGET: // set target
- {
- // Change the movie we're working on.
- const char* target_name = code.read_string(pc+3);
- movie *new_target;
-
- // if the string is blank, we set target to the root movie
- // TODO - double check this is correct?
- if (target_name[0] == '\0')
- new_target = env.find_target((tu_string)"/");
- else
- new_target = env.find_target((tu_string)target_name);
-
- if (new_target == NULL) {
- log_action("ERROR: Couldn't find movie \"%s\" to set
target to!"
- " Not setting target at all...",
- (const char *)target_name);
- }
- else
- env.set_target(new_target);
-
- break;
- }
-
- case SWF::ACTION_GOTOLABEL: // go to labeled frame,
goto_frame_lbl
- {
- const char* frame_label = code.read_string(pc+3);
- movie *target = env.get_target();
- target->goto_labeled_frame(frame_label);
- break;
- }
-
- case SWF::ACTION_WAITFORFRAMEEXPRESSION: // wait for frame
expression (?)
- {
- // Pop the frame number to wait for; if it's not loaded skip
the
- // specified number of actions.
- //
- // Since we don't support incremental loading, pop our arg and
- // don't do anything.
- env.drop(1);
- break;
- }
-
-#if 0
- case SWF::ACTION_DEFINEFUNCTION2: // 0x8E
- code.doActionDefineFunction2(env, with_stack, pc, &next_pc);
- break;
-#endif
-
- case SWF::ACTION_WITH: // with
- {
- int frame = code.read_int16(pc+3);
- UNUSED(frame);
- log_action("-------------- with block start: stack size is
%zd\n", with_stack.size());
- if (with_stack.size() < 8) {
- int block_length = code.read_int16(pc+3);
- int block_end = next_pc + block_length;
- as_object* with_obj = env.top(0).to_object();
- with_stack.push_back(with_stack_entry(with_obj,
block_end));
- }
- env.drop(1);
- break;
- }
-#if 0
- case SWF::ACTION_PUSHDATA: // push_data
- {
- size_t i = pc;
- while (i - pc < length) {
- int type = code[3 + i];
- i++;
- if (type == 0) {
- // string
- const char* str = code.read_string(i+3);
- i += strlen(str) + 1;
- env.push(str);
-
- log_action("----string---- pushed '%s'", str);
- } else if (type == 1) {
-
- float f = code.read_float_little(i+3);
- i += 4;
- env.push(f);
- log_action("----float----- pushed '%g'", f);
- } else if (type == 2) {
- as_value nullvalue;
- nullvalue.set_null();
- env.push(nullvalue);
-
- log_action("----null------ pushed NULL");
- } else if (type == 3) {
- env.push(as_value());
-
- log_action("----undef----- pushed UNDEFINED");
- } else if (type == 4) {
- // contents of register
- int reg = code[3 + i];
- i++;
- if ( isFunction2() ) {
- env.push(*(env.local_register_ptr(reg)));
- log_action("-------------- pushed local
register[%d] = '%s'\n",
- reg,
- env.top(0).to_string());
- } else if (reg < 0 || reg >= 4) {
- env.push(as_value());
- log_error("push register[%d] -- register out of
bounds!\n", reg);
- } else {
- env.push(env.m_global_register[reg]);
- log_action("-------------- pushed global
register[%d] = '%s'\n",
- reg,
- env.top(0).to_string());
- }
-
- } else if (type == 5) {
- bool bool_val = code[i+3] ? true : false;
- i++;
-// log_msg("bool(%d)\n", bool_val);
- env.push(bool_val);
-
- log_action("---bool------- pushed %s",
- (bool_val ? "true" : "false"));
- } else if (type == 6) {
- double d = code.read_double_wacky(i+3);
- i += 8;
- env.push(d);
-
- log_action("-------------- pushed double %g", u.d);
- } else if (type == 7) {
- // int32
- int32_t val = code.read_int32(i+3);
- i += 4;
-
- env.push(val);
-
- log_action("-------------- pushed int32 %d",val);
- } else if (type == 8) {
- int id = code[3 + i];
- i++;
- if (id < (int) code.m_dictionary.size()) {
- env.push(code.m_dictionary[id]);
-
- log_action("----dict------ pushed '%s'",
- code.m_dictionary[id]);
- } else {
- log_error("dict_lookup(%d) is out of bounds!\n",
id);
- env.push(0);
- log_action("-------------- pushed 0");
- }
- } else if (type == 9) {
- int id = code.read_int16(i+3);
- i += 2;
- if (id < (int) code.m_dictionary.size()) {
- env.push(code.m_dictionary[id]);
- log_action("-------------- pushed '%s'\n",
code.m_dictionary[id]);
- } else {
- log_error("dict_lookup(%d) is out of bounds!\n",
id);
- env.push(0);
-
- log_action("-------------- pushed 0");
- }
- }
- }
-
- break;
- }
-#endif
- case SWF::ACTION_BRANCHALWAYS: // branch always (goto)
- {
- int16_t offset = code.read_int16(pc+3);
- next_pc += offset;
- // @@ TODO range checks
- break;
- }
-#if 0
- case SWF::ACTION_GETURL2: // get url 2
- {
- int method = code[pc + 3];
- UNUSED(method);
-
- const char* target = env.top(0).to_string();
- const char* url = env.top(1).to_string();
-
- // If the url starts with "FSCommand:", then this is
- // a message for the host app.
- if (strncmp(url, "FSCommand:", 10) == 0) {
- if (s_fscommand_handler) {
- // Call into the app.
-
(*s_fscommand_handler)(env.get_target()->get_root_interface(), url + 10,
target);
- }
- } else {
-#ifdef EXTERN_MOVIE
-// log_error("get url2: target=%s, url=%s\n", target, url);
-
- movie* target_movie = env.find_target(env.top(0));
- if (target_movie != NULL) {
- movie* root_movie =
env.get_target()->get_root_movie();
- attach_extern_movie(url, target_movie, root_movie);
- } else {
- log_error("get url2: target %s not found\n", target);
- }
-#endif // EXTERN_MOVIE
- }
- env.drop(2);
- break;
- }
-#endif
-
-#if 0
- case SWF::ACTION_DEFINEFUNCTION: // declare function
- doActionDefineFunction(env, with_stack, pc, &next_pc);
- break;
-#endif
-
- case SWF::ACTION_BRANCHIFTRUE: // branch if true
- {
- int16_t offset = code.read_int16(pc+3);
-
- bool test = env.top(0).to_bool();
- env.drop(1);
- if (test) {
- next_pc += offset;
-
- if (next_pc > stop_pc) {
- log_error("branch to offset %d -- this section only
runs to %d\n",
- next_pc,
- stop_pc);
- }
- }
- break;
- }
- case SWF::ACTION_CALLFRAME: // call frame
- {
- // Note: no extra data in this instruction!
- assert(env.m_target);
- env.m_target->call_frame_actions(env.top(0));
- env.drop(1);
-
- break;
- }
-
- case SWF::ACTION_GOTOEXPRESSION: // goto frame expression,
goto_frame_exp
- {
- // From Alexi's SWF ref:
- //
- // Pop a value or a string and jump to the specified
- // frame. When a string is specified, it can include a
- // path to a sprite as in:
- //
- // /Test:55
- //
- // When f_play is ON, the action is to play as soon as
- // that frame is reached. Otherwise, the
- // frame is shown in stop mode.
-
- unsigned char play_flag = code[pc + 3];
- movie::play_state state = play_flag ? movie::PLAY :
movie::STOP;
-
- movie* target = env.get_target();
- bool success = false;
-
- if (env.top(0).get_type() == as_value::UNDEFINED) {
- // No-op.
- } else if (env.top(0).get_type() == as_value::STRING) {
- // @@ TODO: parse possible sprite path...
-
- // Also, if the frame spec is actually a number (not a
label), then
- // we need to do the conversion...
-
- const char* frame_label = env.top(0).to_string();
- if (target->goto_labeled_frame(frame_label)) {
- success = true;
- } else {
- // Couldn't find the label. Try converting to a
number.
- double num;
- if (string_to_number(&num, env.top(0).to_string())) {
- int frame_number = int(num);
- target->goto_frame(frame_number);
- success = true;
- }
- // else no-op.
- }
- } else if (env.top(0).get_type() == as_value::OBJECT) {
- // This is a no-op; see test_goto_frame.swf
- } else if (env.top(0).get_type() == as_value::NUMBER) {
- // Frame numbers appear to be 0-based! @@ Verify.
- int frame_number = int(env.top(0).to_number());
- target->goto_frame(frame_number);
- success = true;
- }
-
- if (success) {
- target->set_play_state(state);
- }
-
- env.drop(1);
- break;
- }
-
- default:
- log_error("Missing handler for action %d", action_id);
- break;
-
- }
-#endif
- }
-#endif // } // End of kept-for reference block
-
}
env.set_target(original_target);
Index: server/swf/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/ASHandlers.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/swf/ASHandlers.cpp 26 Jun 2006 10:12:10 -0000 1.14
+++ server/swf/ASHandlers.cpp 27 Jun 2006 18:45:26 -0000 1.15
@@ -66,35 +66,62 @@
std::vector<std::string> SWFHandlers::_property_names;
-static void unsupported_action_handler(ActionExec& thread)
+// Utility. Try to convert str to a number. If successful,
+// put the result in *result, and return true. If not
+// successful, put 0 in *result, and return false.
+static bool string_to_number(double* result, const char* str)
+{
+ char* tail = 0;
+ *result = strtod(str, &tail);
+ if (tail == str || *tail != 0)
+ {
+ // Failed conversion to Number.
+ return false;
+ }
+ return true;
+}
+
+
+
+
+static void unsupported_action_handler(ActionExec& /*thread*/)
{
log_error("Unsupported action handler invoked");
}
ActionHandler::ActionHandler()
- : _debug(false), _stack_args(0), _arg_format(ARG_NONE),
+ :
+ _name("unsupported"),
_callback(unsupported_action_handler),
- _name("unsupported")
+ _debug(false),
+ _stack_args(0),
+ _arg_format(ARG_NONE)
{
// GNASH_REPORT_FUNCTION;
}
ActionHandler::ActionHandler(action_type type, action_callback_t func)
- : _debug(false), _stack_args(0),_arg_format(ARG_NONE)
+ :
+ _type(type),
+ _callback(func),
+ _debug(false),
+ _stack_args(0),
+ _arg_format(ARG_NONE)
{
// GNASH_REPORT_FUNCTION;
- _type = type;
- _callback = func;
}
ActionHandler::ActionHandler(action_type type, string name,
action_callback_t func)
- : _debug(false), _stack_args(0), _arg_format(ARG_NONE)
+ :
+ _type(type),
+ _name(name),
+ _callback(func),
+ _debug(false),
+ _stack_args(0),
+ _arg_format(ARG_NONE)
{
// GNASH_REPORT_FUNCTION;
- _name = name;
- _type = type;
- _callback = func;
}
ActionHandler::ActionHandler(action_type type, string name,
@@ -454,7 +481,7 @@
{
// GNASH_REPORT_FUNCTION;
- as_environment& env = thread.env;
+ //as_environment& env = thread.env;
const action_buffer& code = thread.code;
assert( code[thread.pc] == SWF::ACTION_TOGGLEQUALITY );
@@ -466,10 +493,11 @@
{
// GNASH_REPORT_FUNCTION;
- as_environment& env = thread.env;
+ //as_environment& env = thread.env;
const action_buffer& code = thread.code;
assert( code[thread.pc] == SWF::ACTION_STOPSOUNDS );
+
sound_handler* s = get_sound_handler();
if (s != NULL)
{
@@ -487,13 +515,12 @@
assert( code[thread.pc] == SWF::ACTION_GOTOFRAME );
- int frame = code[thread.pc + 3] | (code[thread.pc + 4] << 8);
+ int frame = code.read_int16(thread.pc+3);
// 0-based already?
//// Convert from 1-based to 0-based
//frame--;
env.get_target()->goto_frame(frame);
- thread.next_pc = thread.stop_pc;
}
void
@@ -512,7 +539,7 @@
// Two strings as args.
const char* url = code.read_string(pc+3);
- size_t url_len = strlen(url);
+ //size_t url_len = strlen(url);
const char* target = code.read_string(pc+3);
// If the url starts with an "http" or "https",
@@ -573,20 +600,55 @@
SWFHandlers::ActionWaitForFrame(ActionExec& thread)
{
// GNASH_REPORT_FUNCTION;
+
+ as_environment& env = thread.env;
+
// If we haven't loaded a specified frame yet, then we're supposed
// to skip some specified number of actions.
//
// Since we don't load incrementally, just ignore this opcode.
- dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented (no need until we
play while reading)" << endl;
+ env.drop(1);
+
+ dbglogfile << __PRETTY_FUNCTION__
+ << ": unimplemented (no need until we play while reading)"
+ << endl;
}
void
SWFHandlers::ActionSetTarget(ActionExec& thread)
{
// GNASH_REPORT_FUNCTION;
+
as_environment& env = thread.env;
- dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
+ const action_buffer& code = thread.code;
+ size_t pc = thread.pc;
+
+ // Change the movie we're working on.
+ const char* target_name = code.read_string(pc+3);
+ movie *new_target;
+
+ // if the string is blank, we set target to the root movie
+ // TODO - double check this is correct?
+ if (target_name[0] == '\0')
+ {
+ new_target = env.find_target((tu_string)"/");
+ }
+ else
+ {
+ new_target = env.find_target((tu_string)target_name);
+ }
+
+ if (new_target == NULL)
+ {
+ log_action("ERROR: Couldn't find movie \"%s\" "
+ "to set target to! Not setting target at all...",
+ (const char *)target_name);
+ }
+ else
+ {
+ env.set_target(new_target);
+ }
}
void
@@ -594,7 +656,11 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
+ const action_buffer& code = thread.code;
+
+ const char* frame_label = code.read_string(thread.pc+3);
+ movie *target = env.get_target();
+ target->goto_labeled_frame(frame_label);
}
void
@@ -940,7 +1006,7 @@
}
void
-SWFHandlers::ActionThrow(ActionExec& thread)
+SWFHandlers::ActionThrow(ActionExec& /*thread*/)
{
// GNASH_REPORT_FUNCTION;
//as_environment& env = thread.env;
@@ -951,7 +1017,9 @@
SWFHandlers::ActionCastOp(ActionExec& thread)
{
// GNASH_REPORT_FUNCTION;
+
as_environment& env = thread.env;
+
// Get the "super" function
function_as_object* super = env.top(0).to_as_function();
@@ -959,12 +1027,11 @@
as_object* instance = env.top(1).to_object();
// Invalid args!
- if (!super || ! instance) {
- //IF_VERBOSE_ACTION(
+ if (!super || ! instance)
+ {
log_action("-- %s instance_of %s (invalid args?)\n",
env.top(1).to_string(),
env.top(0).to_string());
- //);
env.drop(1);
env.top(0) = as_value();
@@ -972,18 +1039,22 @@
}
env.drop(1);
- if ( instance->instanceOf(super) ) {
+ if ( instance->instanceOf(super) )
+ {
env.top(0) = as_value(instance);
- } else {
+ }
+ else
+ {
env.top(0) = as_value();
}
}
void
-SWFHandlers::ActionImplementsOp(ActionExec& thread)
+SWFHandlers::ActionImplementsOp(ActionExec& /*thread*/)
{
// GNASH_REPORT_FUNCTION;
- as_environment& env = thread.env;
+
+ //as_environment& env = thread.env;
dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
}
@@ -1182,8 +1253,6 @@
SWFHandlers::ActionBranchAlways(ActionExec& thread)
{
// GNASH_REPORT_FUNCTION;
-// as_environment& env = thread.env;
-// dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
int16_t offset = thread.code.read_int16(thread.pc+3);
thread.next_pc += offset;
@@ -1199,6 +1268,8 @@
assert( code[thread.pc] == SWF::ACTION_GETURL );
+ // int method = code[pc + 3];
+
const char* target = env.top(0).to_string();
const char* url = env.top(1).to_string();
@@ -1245,8 +1316,6 @@
size_t& next_pc = thread.next_pc;
size_t& stop_pc = thread.stop_pc;
- //dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
-
int16_t offset = code.read_int16(pc+3);
bool test = env.top(0).to_bool();
@@ -1271,15 +1340,89 @@
{
// GNASH_REPORT_FUNCTION;
as_environment& env = thread.env;
- dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
+
+ // Note: no extra data in this instruction!
+ assert(env.m_target);
+ env.m_target->call_frame_actions(env.top(0));
+ env.drop(1);
}
void
SWFHandlers::ActionGotoExpression(ActionExec& thread)
{
// GNASH_REPORT_FUNCTION;
+
as_environment& env = thread.env;
- dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
+ const action_buffer& code = thread.code;
+ size_t pc = thread.pc;
+
+ //dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
+
+ // From Alexi's SWF ref:
+ //
+ // Pop a value or a string and jump to the specified
+ // frame. When a string is specified, it can include a
+ // path to a sprite as in:
+ //
+ // /Test:55
+ //
+ // When f_play is ON, the action is to play as soon as
+ // that frame is reached. Otherwise, the
+ // frame is shown in stop mode.
+
+ unsigned char play_flag = code[pc + 3];
+ movie::play_state state = play_flag ? movie::PLAY : movie::STOP;
+
+ movie* target = env.get_target();
+ bool success = false;
+
+ if (env.top(0).get_type() == as_value::UNDEFINED)
+ {
+ // No-op.
+ }
+ else if (env.top(0).get_type() == as_value::STRING)
+ {
+ // @@ TODO: parse possible sprite path...
+ //
+ // Also, if the frame spec is actually a number (not a label),
+ // then we need to do the conversion...
+
+ const char* frame_label = env.top(0).to_string();
+ if (target->goto_labeled_frame(frame_label))
+ {
+ success = true;
+ }
+ else
+ {
+ // Couldn't find the label. Try converting to a number.
+ double num;
+ if (string_to_number(&num, env.top(0).to_string()))
+ {
+ int frame_number = int(num);
+ target->goto_frame(frame_number);
+ success = true;
+ }
+ // else no-op.
+ }
+ }
+ else if (env.top(0).get_type() == as_value::OBJECT)
+ {
+ // This is a no-op; see test_goto_frame.swf
+ }
+ else if (env.top(0).get_type() == as_value::NUMBER)
+ {
+ // Frame numbers appear to be 0-based! @@ Verify.
+ int frame_number = int(env.top(0).to_number());
+ target->goto_frame(frame_number);
+ success = true;
+ }
+
+ if (success)
+ {
+ target->set_play_state(state);
+ }
+
+ env.drop(1);
}
void
@@ -2042,7 +2185,7 @@
// Extract name.
// @@ security: watch out for possible missing terminator here!
tu_string name = code.read_string(i);
- i += name.length() + 1;
+ i += name.length() + 1; // add NULL-termination
//cerr << " name:" << name << endl;
@@ -2055,11 +2198,15 @@
// Get the count of local registers used by this function.
uint8 register_count = code[i];
i += 1;
+
+ //cerr << " nregisters:" << nargs << endl;
+
func->set_local_register_count(register_count);
// Flags, for controlling register assignment of implicit args.
uint16 flags = code.read_int16(i);
i += 2;
+
func->set_function2_flags(flags);
// Get the register assignments and names of the arguments.
@@ -2069,12 +2216,14 @@
++i;
// @@ security: watch out for possible missing terminator here!
- func->add_arg(arg_register, code.read_string(i));
- i += func->m_args.back().m_name.length() + 1;
+ const char* arg = code.read_string(i);
+
+ func->add_arg(arg_register, arg);
+ i += strlen(arg)+1;
}
// Get the length of the actual function code.
- int16_t code_size = code.read_int16(thread.pc);
+ int16_t code_size = code.read_int16(i);
assert( code_size >= 0 );
i += 2;
func->set_length(code_size);
@@ -2085,7 +2234,8 @@
// If we have a name, then save the function in this
// environment under that name.
as_value function_value(func);
- if (name.length() > 0) {
+ if (name.length() > 0)
+ {
// @@ NOTE: should this be m_target->set_variable()???
env.set_member(name, function_value);
}
@@ -2106,6 +2256,27 @@
{
// GNASH_REPORT_FUNCTION;
dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
+
+ as_environment& env = thread.env;
+ const action_buffer& code = thread.code;
+ std::vector<with_stack_entry>& with_stack = thread.with_stack;
+
+ size_t pc = thread.pc;
+ size_t next_pc = thread.next_pc;
+
+ log_action("-------------- with block start: stack size is %zd\n",
+ with_stack.size());
+
+ if (with_stack.size() < 8)
+ {
+ int block_length = code.read_int16(pc+3);
+ int block_end = next_pc + block_length;
+ as_object* with_obj = env.top(0).to_object();
+ with_stack.push_back(
+ with_stack_entry(with_obj, block_end)
+ );
+ }
+ env.drop(1);
}
void
@@ -2189,7 +2360,35 @@
SWFHandlers::ActionSetRegister(ActionExec& thread)
{
// GNASH_REPORT_FUNCTION;
- dbglogfile << __PRETTY_FUNCTION__ << ": unimplemented!" << endl;
+
+ as_environment& env = thread.env;
+ const action_buffer& code = thread.code;
+
+ int reg = code[thread.pc + 3];
+
+ // Save top of stack in specified register.
+ if ( thread.isFunction2() )
+ {
+ *(env.local_register_ptr(reg)) = env.top(0);
+
+ log_action("-------------- local register[%d] = '%s'\n",
+ reg, env.top(0).to_string());
+
+ }
+ else if (reg >= 0 && reg < 4)
+ {
+ env.m_global_register[reg] = env.top(0);
+
+ log_action("-------------- global register[%d] = '%s'\n",
+ reg, env.top(0).to_string() );
+
+ }
+ else
+ {
+ log_error("store_register[%d] -- register out of bounds!",
+ reg);
+ }
+
}
} // namespace gnash::SWF
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog server/ActionExec.cpp server/sw...,
Sandro Santilli <=