Checkpoint

This commit is contained in:
Jordan Eldredge 2023-07-23 10:59:57 -07:00
parent 48eb58ea4f
commit 7209ace5ac
34 changed files with 11230 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -47,6 +47,9 @@ class MockGroup {
}
return this.list;
}
islayout() {
return true;
}
}
class MockGuiList {

View file

@ -0,0 +1,50 @@
#!/bin/bash
# Define your JSON file here
JSON_FILE="modern_skins.json"
# Define extraction directories
TEMP_DIR="temp_maki"
FINAL_DIR="extracted_maki"
mkdir -p $TEMP_DIR
mkdir -p $FINAL_DIR
# Function to download a file and extract .maki files
process_url() {
json_node=$(echo "${1}" | base64 --decode)
url=$(echo "${json_node}" | jq -r '.download_url')
file=$(echo "${json_node}" | jq -r '.filename')
echo "Downloading $url..."
# Use wget to download the file
wget -O $file $url
echo "Extracting .maki files from $file..."
# Use unzip to extract .maki files to a temporary directory
unzip -j -o $file "*.maki" -d $TEMP_DIR
# Extract the MD5 hash from the download URL
skin_md5_hash=$(basename $url | cut -d '.' -f1)
# Move the files from temporary directory to the final directory with unique names
for extracted_file in $TEMP_DIR/*.maki; do
base_file=$(basename "$extracted_file")
file_md5_hash=$(md5sum "$extracted_file" | awk '{ print $1 }')
mv "$extracted_file" "$FINAL_DIR/${base_file%.*}_${skin_md5_hash}_${file_md5_hash}.maki"
done
# Remove the downloaded zip file
rm $file
rm -r $TEMP_DIR
}
export -f process_url
export TEMP_DIR
export FINAL_DIR
# Run the function in parallel
jq -r '.data.modern_skins.nodes[] | @base64' $JSON_FILE | parallel -j 10 process_url
echo "Download and extraction completed."

View file

@ -1,5 +1,7 @@
#include "lib/std.mi"
// To compile in VM:
// Navitage to the directory containing this file;
// Z:\projects\webamp\packages\webamp-modern\src\maki\__tests__\fixtures\TestBedSkin\scripts
// From within this directoy (so the compiled .maki file ends up here)
// & '..\..\..\..\..\..\..\webamp-modern\resources\maki_compiler\v1.2.0 (Winamp 5.66)\mc.exe' .\assertions.m
@ -35,4 +37,85 @@ System.onScriptLoaded()
assert(3 / 2 == 1.5, "3 / 2 == 1.5", "Division of two integers results in a float");
assert(1 + 1.5 == 2.5, "1 + 1.5 == 2.5", "Summing an integer and a float results in a float");
assert(1.5 + 1 == 2.5, "1.5 + 1 == 2.5", "Summing a float and an integer results in a float");
assert("Hello" + " world" == "Hello world", "String concatenation", "String concatenation works");
assert(1024 << 2 == 4096, "1024 << 2 == 4096", "Left shift works");
assert(1024 >> 2 == 256, "1024 >> 2 == 256", "Right shift works");
assert(-5 == -5, "-5 == -5", "Unary negative");
Int incrementMe = 5;
assert(incrementMe++ == 5, "5++ == 5", "Postfix increment works");
incrementMe = 5;
assert((incrementMe += 1) == 6, "(incrementMe += 1) == 6", "Plus equals works");
incrementMe = 5;
assert((incrementMe -= 1) == 4, "(incrementMe -= 1) == 4", "Minus equals works");
incrementMe = 5;
assert((incrementMe /= 2) == 2.5, "(incrementMe /= 2) == 2.5", "Divide equals works");
assert(incrementMe == 2.5, "(incrementMe /= 2) == 2.5", "Divide equals works");
incrementMe = 5;
assert(++incrementMe == 6, "++5 == 6", "Prefix increment works");
// An opcode exists for this, but the compiler chokes on it.
// assert(~5 == -6, "~5 == -6", "Bitwise negation works");
// Assignment
Int x = 10;
Int y = x;
assert(x == y, "x == y", "Assignment works");
Int z = x = 100;
assert(z == 100, "z == 10", "Assignment returns a value");
assert(x == 100, "x == 10", "Assignment returns a value");
// Mov semantics
// Maybe primitivs go on the stack as values, and objects go on the stack as pointers?
// 1
// "Hello"
// <memeory addres 12093211923> <-- Some object?
// Move would not make sense on primitives?
// If pushing an object onto the stack just pushes a pointer (variables table offset) then, to mov
// woud look like:
// mov 1, 2
// What if the values on the stack are all offsets into to variables
// but the value in the variables table is actualy a pointer to the heap?
// In that case, a mov is saying lookup the pointer in variable 1 and set it
// as the pointer in variable 2
// For primitives, it could copy the actual values not pointers
Group myGroup = System.getScriptGroup();
Group myOtherGroup = myGroup;
assert(myGroup.isLayout() == true, "myGroup.isLayout() == true", "isLayout works on original value");
assert(myOtherGroup.isLayout() == true, "myOtherGroup.isLayout() == true", "isLayout works on moved value");
// Question to answer: Are there such things as primitives which like
// exclusively on the stack and never get assigned into the variables table?
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;
Int a = 12345;
a++;
// I believe the stack can be thought of as consisting of offsets into the
// variables table. Every value that exists in maki has a place in the
// variables table, including primitives and values not assigned to
// variables.
Double b = 12345.0;
Int c = 155 + 255;
Boolean x = new Group.isLayout();
}

View file

@ -0,0 +1,6 @@
#include "lib/std.mi"
System.onScriptLoaded()
{
Int c = 155 + 255;
}

View file

@ -0,0 +1,35 @@
-- Variables Table ---------------------------------------------------
var# | Class | What
----------------------------------------------------------------------
0000 | System | System*
0001 | Int | NULL
0002 | Int | __deprecated_runtime
0003 | Double | v
0004 | Int | 2
0005 | Int | 65535
0006 | Int | 1
0007 | String | "runtimecheck"
0008 | Int | 0
0009 | Int | last
000A | Int | now
000B | Int | 5000
000C | String | "This script requires "
000D | String | "Winamp 5.66 (skin version 1.36)"
000E | String | "Error"
000F | String | ""
0010 | String | s
0011 | String | "DEBUG"
0012 | Int | s
0013 | Int | 155
0014 | Int | 255
0015 | Int | c
-- Events Table ------------------------------------------------------
var# | Code Pointer | What
----------------------------------------------------------------------
0000 | 0153 | S.o
-- User Functions Table ----------------------------------------------
Code Pointer | What
----------------------------------------------------------------------
0000 | versionCheck
00F2 | debug
011D | debugInt

View file

@ -3,6 +3,7 @@ import path from "path";
import { parse } from "../parser";
import { interpret } from "../interpreter";
import { MockSystem, classResolver } from "./MockSystem";
import { COMMANDS } from "../constants";
/**
* Loads a specially crafted Maki script that can be used to test the behavior
@ -34,6 +35,23 @@ const scriptPath = path.join(
describe(`Maki test harness`, () => {
const maki = fs.readFileSync(scriptPath);
const script = parse(maki);
for (const instruction of script.commands) {
const command = COMMANDS[instruction.opcode];
if (command == null) {
console.log(instruction);
throw new Error("Ooops!");
}
instruction.opcodeName = command.name;
}
for (let i = 0; i < script.variables.length; i++) {
const variable = script.variables[i];
variable.index = i;
}
fs.writeFileSync("./script_dump.json", JSON.stringify(script, null, 2));
const initialVariable = script.variables[0];
if (initialVariable.type !== "OBJECT") {
throw new Error("First variable was not SystemObject.");

View file

@ -0,0 +1,67 @@
import fs from "fs";
import path from "path";
import { parse } from "../parser";
import { interpret } from "../interpreter";
import { MockSystem, classResolver } from "./MockSystem";
import { COMMANDS } from "../constants";
const messages = new Map<string, string[]>();
test.skip("EOF", () => {
const filename =
"xui-statusbar_e28cfc6494da84a543a7fc28ae445403_37800163b91ca58eba885aa054a52b5a.maki";
/*
const maki = fs.readFileSync(
path.join(__dirname, "extracted_maki", filename)
);
*/
const maki = fs.readFileSync(path.join(__dirname, "actioninfo2.maki"));
parse(maki);
});
test.skip("debug function", () => {
const maki = fs.readFileSync(
path.join(
__dirname,
"fixtures",
"TestBedSkin",
"scripts",
"debug",
"debug.maki"
)
);
const script = parse(maki);
// onsole.log(script);
});
describe(`Validate Maki scripts extracted from the db`, () => {
test("Parse all scripts", () => {
const makiFiles = fs.readdirSync(path.join(__dirname, "extracted_maki"));
let smallest = Infinity;
let smallestFile = "";
let smallestScript = null;
for (const makiFile of makiFiles) {
const makiPath = path.join(__dirname, "extracted_maki", makiFile);
const maki = fs.readFileSync(makiPath);
try {
const script = parse(maki);
const hasCall = script.commands.some((c) => c.opcode === 0x18);
const hasStrangeCall = script.commands.some((c) => c.opcode === 0x70);
if (hasStrangeCall && hasCall && maki.length < smallest) {
smallest = maki.length;
smallestFile = makiFile;
smallestScript = script;
console.log(smallestFile, smallest);
}
} catch (e) {
if (!messages.has(e.message)) {
messages.set(e.message, []);
}
messages.get(e.message).push(makiFile + " -- " + maki.length);
}
}
// console.log(messages);
console.log(smallestScript);
console.log(smallestFile, smallest);
});
});

File diff suppressed because it is too large Load diff