⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gameswf_action.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
📖 第 1 页 / 共 5 页
字号:
							log_error("error in call_function: '%s' is not a function\n",								  function_name.c_str());						}					}					else					{						// Hopefully the actual function object is here.						function = env->top(0);					}					int	nargs = (int) env->top(1).to_number();					as_value	result = call_method(function, env, NULL, nargs, env->get_top_index() - 2);					env->drop(nargs + 1);					env->top(0) = result;					break;				}				case 0x3E:	// return				{					// Put top of stack in the provided return slot, if					// it's not NULL.					if (retval)					{						*retval = env->top(0);					}					env->drop(1);					// Skip the rest of this buffer (return from this action_buffer).					pc = stop_pc;					break;				}				case 0x3F:	// modulo				{					as_value	result;					double	y = env->pop().to_number();					double	x = env->pop().to_number();					if (y != 0)					{//						env->top(1).set_double(fmod(env->top(1).to_bool() && env->top(0).to_bool());//						env->drop(1);						result = fmod(x, y);					}//					log_error("modulo x=%f, y=%f, z=%f\n",x,y,result.to_number());					env->push(result);					break;				}				case 0x40:	// new				{					as_value	classname = env->pop();					IF_VERBOSE_ACTION(log_msg("---new object: %s\n",								  classname.to_tu_string().c_str()));					int	nargs = (int) env->pop().to_number();					as_value constructor = env->get_variable(classname.to_tu_string(), with_stack);					as_value new_obj;					if (constructor.get_type() == as_value::C_FUNCTION)					{						// C function is responsible for creating the new object and setting members.						(constructor.to_c_function())(fn_call(&new_obj, NULL, env, nargs, env->get_top_index()));					}					else if (as_as_function* ctor_as_func = constructor.to_as_function())					{						// This function is being used as a constructor; make sure						// it has a prototype object.						ctor_as_func->lazy_create_properties();						assert(ctor_as_func->m_properties);						// Set up the prototype.						as_value	proto;						ctor_as_func->m_properties->get_member("prototype", &proto);						assert(proto.to_object() != NULL);						// Create an empty object, with a ref to the constructor's prototype.						smart_ptr<as_object>	new_obj_ptr(new as_object(proto.to_object()));						// Set up the constructor member.						new_obj_ptr->set_member("constructor", constructor);						new_obj_ptr->set_member_flags("constructor", 1);												new_obj.set_as_object_interface(new_obj_ptr.get_ptr());						// Call the actual constructor function; new_obj is its 'this'.						// We don't need the function result.						call_method(constructor, env, new_obj_ptr.get_ptr(), nargs, env->get_top_index());					}					else					{						if (classname != "String") {							log_error("can't create object with unknown class '%s'\n",								  classname.to_tu_string().c_str());						} else {							log_msg("Created special String class\n");						}					}					env->drop(nargs);					env->push(new_obj);#if 0					log_msg("new object %s at %p\n", classname.to_tu_string().c_str(), new_obj);#endif					break;				}				case 0x41:	// declare local				{					const tu_string&	varname = env->top(0).to_tu_string();					env->declare_local(varname);					env->drop(1);					break;				}				case 0x42:	// init array				{					int	array_size = (int) env->pop().to_number();					//log_msg("xxx init array: size = %d, top of stack = %d\n",					//	// array_size, env->get_top_index());//xxxxx// 					// Call the array constructor, to create an empty array.// 					as_value	result;// 					as_global_array_ctor(fn_call(&result, NULL, env, 0, env->get_top_index()));// 					as_object_interface*	ao = result.to_object();// 					assert(ao);// 					// @@ TODO Set array size.// 					// ao->set_length(whatever); or something// 					// Fill the elements with the initial values from the stack.// 					as_value	index_number;// 					for (int i = 0; i < array_size; i++)// 					{// 						// @@ TODO a set_member that takes an int or as_value?// 						index_number.set_int(i);// 						ao->set_member(index_number.to_string(), env->pop());// 					}// 					env->push(result);// 					//log_msg("xxx init array end: top of stack = %d, trace(top(0)) =",// 					//	env->get_top_index());//xxxxxxx					as_global_trace(fn_call(NULL, NULL, env, 1, env->get_top_index()));	//xxxx					break;				}				case 0x43:	// declare object				{					// @@ TODO					log_error("todo opcode: %02X\n", action_id);					break;				}				case 0x44:	// type of				{					switch(env->top(0).get_type())					{					case as_value::UNDEFINED:						env->top(0).set_string("undefined");						break;					case as_value::STRING:						env->top(0).set_string("string");						break;					case as_value::NUMBER:						env->top(0).set_string("number");						break;					case as_value::BOOLEAN:						env->top(0).set_string("boolean");						break;					case as_value::OBJECT:						env->top(0).set_string("object");						break;					case as_value::NULLTYPE:						env->top(0).set_string("null");						break;					case as_value::AS_FUNCTION:					case as_value::C_FUNCTION:						env->top(0).set_string("function");						break;					default:						log_error("typeof unknown type: %02X\n", env->top(0).get_type());						break;					}					break;				}				case 0x45:	// get target				{					// @@ TODO					log_error("todo opcode: %02X\n", action_id);					break;				}				case 0x46:	// enumerate				{					as_value var_name = env->pop();					const tu_string& var_string = var_name.to_tu_string();					as_value variable = env->get_variable(var_string, with_stack);					if (variable.to_object() == NULL)					{						break;					}					const as_object* object = (as_object*) (variable.to_object());					// The end of the enumeration					as_value nullvalue;					nullvalue.set_null();					env->push(nullvalue);					IF_VERBOSE_ACTION(log_msg("---enumerate - push: NULL\n"));					stringi_hash<as_member>::const_iterator it = object->m_members.begin();					while (it != object->m_members.end())					{						const as_member member = (it.get_value());						if (! member.get_member_flags().get_dont_enum())						{							env->push(as_value(it.get_key()));							IF_VERBOSE_ACTION(log_msg("---enumerate - push: %s\n",										  it.get_key().c_str()));						}													++it;					}					const as_object * prototype = (as_object *) object->m_prototype;					if (prototype != NULL)					{						stringi_hash<as_member>::const_iterator it = prototype->m_members.begin();						while (it != prototype->m_members.end())						{							const as_member member = (it.get_value());							if (! member.get_member_flags().get_dont_enum())							{								env->push(as_value(it.get_key()));								IF_VERBOSE_ACTION(log_msg("---enumerate - push: %s\n",											  it.get_key().c_str()));							}															++it;						};					}					break;				}				case 0x47:	// add_t (typed)				{					if (env->top(0).get_type() == as_value::STRING					    || env->top(1).get_type() == as_value::STRING)					{						env->top(1).convert_to_string_versioned(version);						env->top(1).string_concat(env->top(0).to_tu_string_versioned(version));					}					else					{						env->top(1) += env->top(0);					}					env->drop(1);					break;				}				case 0x48:	// less than (typed)				{					if (env->top(1).get_type() == as_value::STRING)					{						env->top(1).set_bool(env->top(1).to_tu_string() < env->top(0).to_tu_string());					}					else					{						env->top(1).set_bool(env->top(1) < env->top(0));					}					env->drop(1);					break;				}				case 0x49:	// equal (typed)				{					// @@ identical to untyped equal, as far as I can tell...					env->top(1).set_bool(env->top(1) == env->top(0));					env->drop(1);					break;				}				case 0x4A:	// to number				{					env->top(0).convert_to_number();					break;				}				case 0x4B:	// to string				{					env->top(0).convert_to_string_versioned(version);					break;				}				case 0x4C:	// dup					env->push(env->top(0));					break;								case 0x4D:	// swap				{					as_value	temp = env->top(1);					env->top(1) = env->top(0);					env->top(0) = temp;					break;				}				case 0x4E:	// get member				{                                        as_object_interface*    obj = env->top(1).to_object();                                        // Special case: String has a member "length"                                        if (obj == NULL                                            && env->top(1).get_type() == as_value::STRING                                            && env->top(0).to_tu_stringi() == "length")					{						int     len = env->top(1).to_tu_string_versioned(version).utf8_length();                                                env->top(1).set_int(len);					}                                        else					{						env->top(1).set_undefined();						// int	nargs = (int) env->top(1).to_number();						if (obj) {							obj->get_member(env->top(0).to_tu_string(), &(env->top(1)));							if (env->top(1).to_object() == NULL) {								IF_VERBOSE_ACTION(log_msg("-- get_member %s=%s\n",											  env->top(0).to_tu_string().c_str(),											  env->top(1).to_tu_string().c_str()));							} else {								IF_VERBOSE_ACTION(log_msg("-- get_member %s=%s at %p\n",											  env->top(0).to_tu_string().c_str(),											  env->top(1).to_tu_string().c_str(), env->top(1).to_object()));							}						}						else						{							// @@ log error?						}					}                                        env->drop(1);                                        break;									}				case 0x4F:	// set member				{					as_object_interface*	obj = env->top(2).to_object();					if (obj)					{						obj->set_member(env->top(1).to_tu_string(), env->top(0));						IF_VERBOSE_ACTION(							log_msg("-- set_member %s.%s=%s\n",								env->top(2).to_tu_string().c_str(),								env->top(1).to_tu_string().c_str(),								env->top(0).to_tu_string().c_str()));					}					else					{						// Invalid object, can't set.						IF_VERBOSE_ACTION(							log_msg("-- set_member %s.%s=%s on invalid object!\n",								env->top(2).to_tu_string().c_str(),								env->top(1).to_tu_string().c_str(),								env->top(0).to_tu_string().c_str()));					}					env->drop(3);					break;				}				case 0x50:	// increment					env->top(0) += 1;					break;				case 0x51:	// decrement					env->top(0) -= 1;					break;				case 0x52:	// call method				{					int	nargs = (int) env->top(2).to_number();					as_value	result;					const tu_string&	method_name = env->top(0).to_tu_string();					as_object_interface*	obj = env->top(1).to_object();					if (obj)					{						as_value	method;						if (obj->get_member(method_name, &method))						{							if (method.get_type() != as_value::C_FUNCTION							    && method.get_type() != as_value::AS_FUNCTION)							{								log_error("error: call_method: '%s' is not a method\n",									  method_name.c_str());							}							else							{								result = call_method(									method,									env,									obj,									nargs,									env->get_top_index() - 3);							}						}						else						{							log_error("error: call_method can't find method %s\n",								  method_name.c_str());						}					}					else if (env->top(1).get_type() == as_value::STRING)					{						// Handle methods on literal strings.						string_method(							fn_call(&result, NULL, env, nargs, env->get_top_index() - 3),							method_name.to_tu_stringi(),							env->top(1).to_tu_string_versioned(version));					}					else if (env->top(1).get_type() == as_value::C_FUNCTION)					{						// Catch method calls on String						// constructor.  There may be a cleaner						// way to do this. Perhaps we call the						// constructor function with a special flag, to						// indicate that it's a method call?						if (env->top(1).to_c_function() == string_ctor)						{							tu_string dummy;							string_method(								fn_call(&result, NULL, env, nargs, env->get_top_index() - 3),								method_name.to_tu_stringi(),								dummy);						}						else						{							log_error("error: method call on unknown c function.\n");						}					}					else					{						if (env->top(1).get_type() == as_value::NUMBER						    && method_name == "toString")						{							// Numbers have a .toString() method.							result.set_tu_string(env->top(1).to_tu_string());						}						else						{							log_error("error: call_method '%s' on invalid object.\n",								  method_name.c_str());						}					}					env->drop(nargs + 2);					env->top(0) = result;					break;				}				case 0x53:	// new method					// @@ TODO					log_error("todo opcode: %02X\n", action_id);					break;				case 0x54:	// instance of					// @@ TODO					log_error("todo opcode: %02X\n", action_id);					break;				case 0x55:	// enumerate object					// @@ TODO					log_error("todo opcode: %02X\n", action_id);					break;				case 0x60:	// bitwise and					env->top(1) &= env->top(0);					env->drop(1);					break;				case 0x61:	// bitwise or					env->top(1) |= env->top(0);					env->drop(1);					break;				case 0x62:	// bitwise xor					env->top(1) ^= env->top(0);					env->drop(1);					break;				case 0x63:	// shift left					env->top(1).shl(env->top(0));					env->drop(1);					break;				case 0x64:	// shift right (signed)					env->top(1).asr(env->top(0));					env->drop(1);					break;				case 0x65:	// shift right (unsigned)					env->top(1).lsr(env->top(0));					env->drop(1);					break;				case 0x66:	// strict equal					if (env->top(1).get_type() != env->top(0).get_type())					{						// Types don't match.						env->top(1).set_bool(false);						env->drop(1);					}					else					{						env->top(1).set_bool(env->top(1) == env->top(0));						env->drop(1);					}					break;				case 0x67:	// gt (typed)					if (env->top(1).get_type() == as_value::STRING)					{						env->top(1).set_bool(env->top(1).to_tu_string() > env->top(0).to_tu_string());					}					else					{						env->top(1).set_bool(env->top(1).to_number() > env->top(0).to_number());					}					env->drop(1);					break;				case 0x68:	// string gt					env->top(1).set_bool(env->top(1).to_tu_string() > env->top(0).to_tu_string());					env->drop(1);					break;				case 0x69:	// extends					log_error("todo opcode: %02X\n", action_id);					break;				}				pc++;	// advance to next action.			}			else			{				IF_VERBOSE_ACTION(log_msg("EX:\t"); log_disasm(&m_buffer[pc]));				// Action containing extra data.				int	length = 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -