VID_NOTHING = 0x0, // dummy
VID_OPERATOR_ASSIGN = 0x1,
VID_OPERATOR_ADD = 0x2,
- VID_OPERATOR_SUBTRACT = 0x3, // guess
+ VID_OPERATOR_SUBTRACT = 0x3,
VID_OPERATOR_MULTIPLY = 0x4,
- VID_OPERATOR_DIVIDE = 0x5, // guess
- VID_UNK_6 = 0x6,
-
+ VID_OPERATOR_DIVIDE = 0x5,
+ VID_OPERATOR_MOD = 0x6,
+ VID_OPERATOR_POSITIVE = 0x7,
VID_OPERATOR_NEGATE = 0x8,
VID_OPERATOR_NOT = 0x9,
-
+ VID_P_INCREMENT = 0xa,
+ VID_P_DECREMENT = 0xb,
VID_INCREMENT = 0xc,
- VID_DECREMENT = 0xd, // guess
+ VID_DECREMENT = 0xd,
VID_OPERATOR_EQUAL = 0xe,
VID_OPERATOR_NOT_EQUAL = 0xf,
- VID_OPERATOR_CASE_LABEL = 0x10, // same as VID_OPERATOR_EQUAL, just
- // used in switch statements
-
+ VID_OPERATOR_IDENTITY = 0x10, // === operator; used in case labels
+ VID_OPERATOR_NON_IDENTITY = 0x11,
VID_OPERATOR_LT = 0x12,
VID_OPERATOR_LTE = 0x13,
- VID_OPERATOR_GT = 0x14,
- VID_OPERATOR_GTE = 0x15,
-
- VID_UNK_1A = 0x1a,
-
+ VID_OPERATOR_GTE = 0x14,
+ VID_OPERATOR_GT = 0x15,
+
+ VID_OPERATOR_TYPEOF = 0x18,
+ VID_OPERATOR_B_AND = 0x19,
+ VID_OPERATOR_B_XOR = 0x1a,
+ VID_OPERATOR_B_OR = 0x1b,
+ VID_OPERATOR_B_NOT = 0x1c,
+ VID_OPERATOR_LSHIFT = 0x1d,
+ VID_OPERATOR_RSHIFT = 0x1e,
+ VID_OPERATOR_URSHIFT = 0x1f,
VID_STACK_PUSH = 0x20,
VID_END_STMT = 0x22,
VID_CONST_INT = 0x26,
VID_CONST_FLOAT = 0x27,
VID_CONST_STRING = 0x28,
-
+ VID_CONST_OBJECT = 0x29,
VID_FUNCTION = 0x2a,
VID_ARRAY = 0x2b, // start an array constant
VID_THIS = 0x2c,
// items off the stack
VID_UNSET = 0x32, // guess; looks like above, but only with one
// item
-
+ VID_OBJ_ADD_ATTR = 0x33,
VID_ARRAY_INDEX = 0x34,
VID_ARRAY_INDEX_ASSIGN = 0x36,
VID_JUMP_FALSE = 0x3b,
VID_CALL_FUNC = 0x3c,
VID_CALL_METHOD = 0x3d,
- VID_CALL_INBUILT = 0x3e,
+ VID_CALL_NEW = 0x3e,
VID_RETURN = 0x3f,
VID_END = 0x45,
+ VID_DEBUG_FILE = 0x46,
+ VID_DEBUG_LINE = 0x47,
VID_MAKE_FLOAT_ARRAY = 0x49 // weird??
};
L"SUBTRACT",
L"MULTIPLY",
L"DIVIDE",
- L"UNK_6",
- L"UNKNOWN_7",
+ L"MODULUS",
+ L"POSITIVE",
L"NEGATE",
L"NOT",
- L"UNKNOWN_A",
- L"UNKNOWN_B",
+ L"PRE_INCREMENT",
+ L"PRE_DECREMENT",
L"INCREMENT",
L"DECREMENT",
L"TEST_EQUAL",
L"TEST_NOT_EQUAL",
- L"TEST_CASE_EQUAL",
- L"UNKNOWN_11",
+ L"TEST_IDENTITY",
+ L"TEST_NON_IDENTITY",
L"TEST_LESS_THAN",
L"TEST_LESS_EQUAL_THAN",
- L"TEST_MORE_THAN",
L"TEST_MORE_EQUAL_THAN",
+ L"TEST_MORE_THAN",
L"UNKNOWN_16",
L"UNKNOWN_17",
- L"UNKNOWN_18",
- L"UNKNOWN_19",
- L"UNK_1A",
- L"UNKNOWN_1B",
- L"UNKNOWN_1C",
- L"UNKNOWN_1D",
- L"UNKNOWN_1E",
- L"UNKNOWN_1F",
+ L"TYPEOF",
+ L"BINARY_AND",
+ L"BINARY_XOR",
+ L"BINARY_OR",
+ L"BINARY_NOT",
+ L"LSHIFT",
+ L"RSHIFT",
+ L"UNSIGNED_RSHIFT",
L"STACK_PUSH",
L"UNKNOWN_21",
L"END_STATEMENT",
L"CONST_INT",
L"CONST_FLOAT",
L"CONST_STRING",
- L"UNKNOWN_29",
+ L"CONST_OBJECT",
L"FUNCTION",
L"CONST_ARRAY",
L"THIS_OBJECT",
L"METHOD",
L"SET",
L"UNSET",
- L"UNKNOWN_33",
+ L"OBJECT_ADD_ATTRIBUTE",
L"ARRAY_INDEX",
L"UNKNOWN_35",
L"ARRAY_INDEX_ASSIGN",
L"JUMP_IF_FALSE",
L"CALL_FUNCTION",
L"CALL_METHOD",
- L"CALL_INBUILT",
+ L"CALL_NEW",
L"RETURN",
L"UNKNOWN_40",
L"UNKNOWN_41",
L"UNKNOWN_43",
L"UNKNOWN_44",
L"END_SCRIPT",
- L"UNKNOWN_46",
- L"UNKNOWN_47",
+ L"DEBUG_FILE",
+ L"DEBUG_LINE",
L"UNKNOWN_48",
L"MAKE_FLOAT_ARRAY"
};
}
break;
case VID_CONST_INT:
+ case VID_DEBUG_LINE:
fwprintf (out, L" %u", in->code[i].val.u32);
break;
case VID_CONST_FLOAT:
fwprintf (out, L" %#g", in->code[i].val.f);
break;
case VID_CONST_STRING:
+ case VID_DEBUG_FILE:
CHECK_INDEX (in->numText, "text");
fwprintf (out, L" \"%ls\"", in->pText[in->code[i].val.u32]);
break;
case VID_METHOD:
case VID_UNK_31:
case VID_UNSET:
+ case VID_OBJ_ADD_ATTR:
CHECK_INDEX (in->numProp, "property");
fwprintf (out, L" %ls", in->pProp[in->code[i].val.u32]);
break;
case VID_FUNCTION:
if (in->code[i].id >> 16 & 0xFF)
warning
- ("Unexpected flag value for function at line %d, expected 0, got %d",
+ ("Unexpected localvars value for function at line %d, expected 0, got %d",
i + 1, in->code[i].id >> 16 & 0xFF);
- fwprintf (out, L" args=%u, flag=%u, start_line=%u",
+ fwprintf (out, L" args=%u, localvars=%u, start_line=%u",
(in->code[i].id >> 8) & 0xFF, (in->code[i].id >> 24) & 0xFF,
in->code[i].val.u32 + 1);
break;
// function calls
case VID_CALL_FUNC:
case VID_CALL_METHOD:
- case VID_CALL_INBUILT:
+ case VID_CALL_NEW:
fwprintf (out, L" args=%u", in->code[i].val.u32);
break;
case VID_OPERATOR_SUBTRACT:
case VID_OPERATOR_MULTIPLY:
case VID_OPERATOR_DIVIDE:
- case VID_UNK_6:
+ case VID_OPERATOR_MOD:
+ case VID_OPERATOR_POSITIVE:
case VID_OPERATOR_NEGATE:
case VID_OPERATOR_NOT:
+ case VID_P_INCREMENT:
+ case VID_P_DECREMENT:
case VID_INCREMENT:
case VID_DECREMENT:
+ case VID_OPERATOR_TYPEOF:
case VID_OPERATOR_EQUAL:
case VID_OPERATOR_NOT_EQUAL:
- case VID_OPERATOR_CASE_LABEL:
+ case VID_OPERATOR_IDENTITY:
+ case VID_OPERATOR_NON_IDENTITY:
case VID_OPERATOR_LT:
case VID_OPERATOR_LTE:
case VID_OPERATOR_GT:
case VID_OPERATOR_GTE:
- case VID_UNK_1A:
+ case VID_OPERATOR_B_AND:
+ case VID_OPERATOR_B_XOR:
+ case VID_OPERATOR_B_OR:
+ case VID_OPERATOR_B_NOT:
+ case VID_OPERATOR_LSHIFT:
+ case VID_OPERATOR_RSHIFT:
+ case VID_OPERATOR_URSHIFT:
case VID_STACK_PUSH:
case VID_END_STMT:
case VID_CONST_NULL:
case VID_CONST_EMPTYARRAY:
+ case VID_CONST_OBJECT:
case VID_ARRAY:
case VID_THIS:
case VID_ARRAY_INDEX:
break;
case VID_CONST_INT:
case VID_UNNAMED_VAR:
+ case VID_DEBUG_LINE:
swscanf (arg, L"%u", &argNum);
break;
case VID_CONST_FLOAT:
break;
case VID_CONST_STRING:
+ case VID_DEBUG_FILE:
{
if (arg[0] != '"' || arg[wcslen (arg) - 1] != '"') {
warning ("[line %d] Bad string style.", lineCount);
case VID_METHOD:
case VID_UNK_31:
case VID_UNSET:
+ case VID_OBJ_ADD_ATTR:
argNum =
VsmxAddText ((void **) &ret->prop, &oProp, &ret->lenProp,
&ret->numProp, arg, sizeof (*(ret->prop)));
int iArgs, iFlag;
// TODO: better parser here
- swscanf (arg, L"args=%u, flag=%u, start_line=%u", &iArgs, &iFlag,
+ swscanf (arg, L"args=%u, localvars=%u, start_line=%u", &iArgs, &iFlag,
&argNum);
argNum--;
opNum2 = ((iFlag & 0xFF) << 24) | ((iArgs & 0xFF) << 8) | opNum2;
break;
case VID_CALL_FUNC:
case VID_CALL_METHOD:
- case VID_CALL_INBUILT:
+ case VID_CALL_NEW:
swscanf (arg, L"args=%u", &argNum);
break;
case VID_OPERATOR_SUBTRACT:
case VID_OPERATOR_MULTIPLY:
case VID_OPERATOR_DIVIDE:
- case VID_UNK_6:
+ case VID_OPERATOR_MOD:
+ case VID_OPERATOR_POSITIVE:
case VID_OPERATOR_NEGATE:
case VID_OPERATOR_NOT:
+ case VID_P_INCREMENT:
+ case VID_P_DECREMENT:
case VID_INCREMENT:
case VID_DECREMENT:
+ case VID_OPERATOR_TYPEOF:
case VID_OPERATOR_EQUAL:
case VID_OPERATOR_NOT_EQUAL:
- case VID_OPERATOR_CASE_LABEL:
+ case VID_OPERATOR_IDENTITY:
+ case VID_OPERATOR_NON_IDENTITY:
case VID_OPERATOR_LT:
case VID_OPERATOR_LTE:
case VID_OPERATOR_GT:
case VID_OPERATOR_GTE:
- case VID_UNK_1A:
+ case VID_OPERATOR_B_AND:
+ case VID_OPERATOR_B_XOR:
+ case VID_OPERATOR_B_OR:
+ case VID_OPERATOR_B_NOT:
+ case VID_OPERATOR_LSHIFT:
+ case VID_OPERATOR_RSHIFT:
+ case VID_OPERATOR_URSHIFT:
case VID_STACK_PUSH:
case VID_END_STMT:
case VID_CONST_NULL:
case VID_CONST_EMPTYARRAY:
+ case VID_CONST_OBJECT:
case VID_ARRAY:
case VID_THIS:
case VID_ARRAY_INDEX:
wchar str[MAX_TEXT_LEN]; // a bit of RAM wastage perhaps
VSMXGroup item;
int arrayFlag;
+ int objectFlag;
VsmxDecompileStack *prev;
uint32_t depth;
for (i = 0; i < in->codeGroups; i++) {
item.str[0] = 0;
item.arrayFlag = 0;
+ item.objectFlag = 0;
item.item.id = 0;
item.item.val.u32 = 0;
case VID_OPERATOR_DIVIDE:
if (!op[0])
wcscpy (op, L"/");
- case VID_UNK_6:
+ case VID_OPERATOR_MOD:
if (!op[0])
- wcscpy (op, L"<op6>"); // TODO: fix dummy
+ wcscpy (op, L"%");
case VID_OPERATOR_EQUAL:
if (!op[0])
wcscpy (op, L"==");
case VID_OPERATOR_NOT_EQUAL:
if (!op[0])
wcscpy (op, L"!=");
+ case VID_OPERATOR_IDENTITY:
+ if (!op[0])
+ wcscpy (op, L"===");
+ case VID_OPERATOR_NON_IDENTITY:
+ if (!op[0])
+ wcscpy (op, L"!==");
case VID_OPERATOR_LT:
if (!op[0])
wcscpy (op, L"<");
case VID_OPERATOR_GTE:
if (!op[0])
wcscpy (op, L">=");
- case VID_UNK_1A:
+ case VID_OPERATOR_B_AND:
if (!op[0])
- wcscpy (op, L"<op1A>"); // TODO: fix dummy
+ wcscpy (op, L"&");
+ case VID_OPERATOR_B_XOR:
+ if (!op[0])
+ wcscpy (op, L"^");
+ case VID_OPERATOR_B_OR:
+ if (!op[0])
+ wcscpy (op, L"|");
+ case VID_OPERATOR_LSHIFT:
+ if (!op[0])
+ wcscpy (op, L"<<");
+ case VID_OPERATOR_RSHIFT:
+ if (!op[0])
+ wcscpy (op, L">>");
+ case VID_OPERATOR_URSHIFT:
+ if (!op[0])
+ wcscpy (op, L">>>");
{ // TODO: need to consider when to use brackets
VsmxDecompileStack *left, *right;
}
break;
+ case VID_OPERATOR_POSITIVE:
+ if (!op[0])
+ wcscpy (op, L"+");
case VID_OPERATOR_NEGATE:
if (!op[0])
wcscpy (op, L"-");
case VID_OPERATOR_NOT:
if (!op[0])
wcscpy (op, L"!");
+ case VID_OPERATOR_B_NOT:
+ if (!op[0])
+ wcscpy (op, L"~");
+ case VID_OPERATOR_TYPEOF:
+ if (!op[0])
+ wcscpy (op, L"typeof ");
{
VsmxDecompileStack *prev;
}
break;
+ case VID_P_INCREMENT:
case VID_INCREMENT:
if (!op[0])
wcscpy (op, L"++");
+ case VID_P_DECREMENT:
case VID_DECREMENT:
if (!op[0])
wcscpy (op, L"--");
prev = VsmxDecompileStackPop (&stack);
// swprintf(item.str, MAX_TEXT_LEN, L"-(%s)", prev->str);
- SWPRINTF_ITEM ("(%ls)%ls", prev->str, op);
+ if (in->code[i].id & 0xFF == VID_P_INCREMENT || in->code[i].id & 0xFF == VID_P_DECREMENT)
+ SWPRINTF_ITEM ("%ls(%ls)", op, prev->str);
+ else
+ SWPRINTF_ITEM ("(%ls)%ls", prev->str, op);
VsmxDecompileStackPush (&stack, &item);
free (prev);
}
}
break;
+ case VID_CONST_OBJECT:
+ wcscpy (item.str, L"{}");
+ item.objectFlag = 1;
+ VsmxDecompileStackPush (&stack, &item);
+ break;
+ case VID_OBJ_ADD_ATTR:
+ {
+ VsmxDecompileStack *obj, *prev;
+
+ CHECK_INDEX (in->numProp, "prop");
+
+ prev = VsmxDecompileStackPop (&stack);
+ obj = VsmxDecompileStackPop (&stack);
+ if (obj->objectFlag == 0) {
+ warning ("Object elem being pushed, but object not found at %d!", i);
+ } else if (obj->objectFlag == 1) { // first element
+ SWPRINTF_ITEM ("{ %ls: %ls }", in->pProp[in->code[i].val.u32], prev->str);
+ item.objectFlag = 2;
+ VsmxDecompileStackPush (&stack, &item);
+ } else {
+ uint32_t aLen = wcslen (obj->str);
+
+ if (aLen < 3) {
+ error ("Internal object handling error at %d!", i);
+ return 1;
+ }
+ obj->str[aLen - 2] = L'\0';
+ SWPRINTF_ITEM ("%ls, %ls: %ls }", obj->str, in->pProp[in->code[i].val.u32], prev->str);
+ item.objectFlag = 2;
+ VsmxDecompileStackPush (&stack, &item);
+ }
+ free (prev);
+ free (obj);
+ }
+ break;
+
case VID_ARRAY:
wcscpy (item.str, L"[]");
item.arrayFlag = 1;
prev = VsmxDecompileStackPop (&stack);
array = VsmxDecompileStackPop (&stack);
- if (!array->arrayFlag) {
+ if (array->arrayFlag == 0) {
warning ("Array elem being pushed, but array not found at %d!", i);
} else if (array->arrayFlag == 1) { // first element
SWPRINTF_ITEM ("[ %ls ]", prev->str);
case VID_CALL_FUNC:
case VID_CALL_METHOD:
- case VID_CALL_INBUILT:
+ case VID_CALL_NEW:
{
if (stack->depth < in->code[i].val.u32) {
error
// swprintf(item.str, MAX_TEXT_LEN, L"%s( )", prev->str);
SWPRINTF_ITEM ("%ls()", prev->str);
}
+ if(in->code[i].id & 0xFF == VID_CALL_NEW) {
+ SWPRINTF_ITEM ("new %ls", item.str);
+ }
free (prev);
VsmxDecompileStackPush (&stack, &item);
}
}
break;
+ // ignore debugging stuff
+ case VID_DEBUG_FILE:
+ case VID_DEBUG_LINE:
+ break;
+
default:
warning ("Unknown id 0x%x at %d", in->code[i].id, i);
SWPRINTF_ITEM ("<< UNKNOWN 0x%x 0x%x >>", in->code[i].id,