• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Jass Script Helper

Tool for search unused locals, globals, functions.
And for optimize script and detect leaks.
Can save optimized script to file.

New version of Jass Script Warn Helper v2

12.05.2017: First release

13.05.2017: 1.2a version
+ Leak scanner
+ Bug fixes
+ Save script with remove unused globals, locals, functions, and fix leaks.

15.05.2017: 1.3a version
+ Configuration file! (can be edited default and hidden options)
+ Readme file :)

15.05.2017: 1.3b version
= Bug fixes (fix some cases bad detecting leaks)
15.05.2017: 1.4a version
+ fix missing INIFileParser.dll file
+ added first optimization in code
+ added warning messages
17.05.2017: 1.4e version
+ bug fixes
+ disable warning message for optimization

Features:
• Search unused globals
• Search unused locals
• Search unused functions
• Search leaks in code
• Optimize code
• Save result war3map.j file
• Uses multithread but too very slow if big input file :)


Example with default settings:


Example input:
Code:
native MergeUnits           takes integer qty, integer a, integer b, integer make returns boolean




globals

    integer test1 = 0
    integer test2 = 0
    unit test3 = 0
    item test4 = 0
 
    code l__Code
    integer l__Int
 
endglobals


function UnusedFunction takes nothing returns nothing
    call Print("Hello world")
endfunction


function TestLeakArg takes unit u returns nothing
    set u = CreateUnit(...)
    call SetUnitSomething(u,...)
endfunction


function TestNoLeakArg takes unit u returns nothing
    set u = CreateUnit(...)
    call SetUnitSomething(u,...)
    set u = null
endfunction

function TestLeakVar takes nothing returns nothing
    local unit u = CreateUnit(...)
    call SetUnitSomething(u,...)
endfunction


function TestNoLeakVar takes unit u returns nothing
    local unit u = CreateUnit(...)
    call SetUnitSomething(u,...)
    if SomeFunc( ) == true then
        set u = null
        return
    endif
 
    if SomeFunc2( ) == true then
        return
    endif
 
    set u = null
    return
endfunction



function UseGlobals takes nothing returns nothing
    call TestFunction(test3)
    set test4 = ...
endfunction


function TestTypeCast takes nothing returns nothing
    local integer l__Code
    local code l__Int
endfunction

function TestUnusedLocal takes nothing returns nothing
    local unit u1 = null
    local unit u2 = u1
    local unit u3 = null
    local unit u4 = u1
    local unit u5 = null
    call TestFunction(...)
    call TestFunction(u2)
    set u2 = u3//
 
endfunction


function main takes nothing returns nothing
    call TestLeakArg( ... )
    call TestNoLeakArg( ... )
    call TestLeakVar( ... )
    call TestNoLeakVar( ... )
    call TestUnusedLocal( ... )
endfunction





function config takes nothing returns nothing
    call UseGlobals( ... )
endfunction

Example output:
Code:
native MergeUnits           takes integer qty, integer a, integer b, integer make returns boolean
globals
    unit test3 = 0
    item test4 = 0
 
    code l__Code
    integer l__Int
endglobals


function TestLeakArg takes unit u returns nothing
    set u = CreateUnit(...)
    call SetUnitSomething(u,...)
    set u = null
endfunction


function TestNoLeakArg takes unit u returns nothing
    set u = CreateUnit(...)
    call SetUnitSomething(u,...)
    set u = null
endfunction

function TestLeakVar takes nothing returns nothing
    local unit u = CreateUnit(...)
    call SetUnitSomething(u,...)
    set u = null
endfunction


 
 
function TestNoLeakVar takes unit u returns nothing
    local unit u = CreateUnit(...)
    call SetUnitSomething(u,...)
    if SomeFunc( ) == true then
        set u = null
        return
    endif
    if SomeFunc2( ) == true then
        set u = null
        return
    endif
    set u = null
    return
endfunction



function UseGlobals takes nothing returns nothing
    call TestFunction(test3)
    set test4 = ...
endfunction
//Found typecast function. Local variable have same name as global variable!


function TestTypeCast takes nothing returns nothing
    local integer l__Code
    local code l__Int
endfunction

//
 
function TestUnusedLocal takes nothing returns nothing
    local unit u1 = null
    local unit u2 = u1
    local unit u3 = null
    call TestFunction(...)
    call TestFunction(u2)
    set u2 = u3
    set u2 = null
endfunction


function main takes nothing returns nothing
    call TestLeakArg( ... )
    call TestNoLeakArg( ... )
    call TestLeakVar( ... )
    call TestNoLeakVar( ... )
    call TestUnusedLocal( ... )
endfunction





function config takes nothing returns nothing
    call UseGlobals( ... )
endfunction
Contents

Jass Script Helper 1.4e (Binary)

Reviews
eejin
The tool does what it promises and the UI is simple and to the point. While it doesn't crash when using a map with VJass the output may not be entirely correct so this is something to keep in mind. As the tool warns do not replace your war3map.j with...
Level 13
Joined
Nov 7, 2014
Messages
571
input
JASS:
function TestLeakArg takes unit u returns nothing
    set u = CreateUnit(...)
    call SetUnitSomething(u,...)
endfunction

output
JASS:
function TestLeakArg takes unit u returns nothing
    set u = CreateUnit(...)
    call SetUnitSomething(u,...)
    set u = null
endfunction

I think arguments don't need to be set to null, they get pushed on the stack (push instruction) and cleaned up with the cleanstack instruction, so a handle's reference count doesn't change at all or it first gets incremented by the push and then decremented by the cleanstack, either way the ref count stays the same.

Edit: it could be the 0x08 (poparg) instruction as well, I don't know =)

Its nice that the tool can detect typecasting, rather than removing "unused" functions/globals =).
 
Last edited:
Level 9
Joined
Jun 17, 2010
Messages
217
arg auto cleaned after function execute ? :( I don't know :)

Update 1.3a:
• Added configuration and readme files


Possible in new version i can add auto code optimization ( but i don't know what need optimize :) )


Example :

Unoptimized??:
Code:
globals
endglobals

function1 ..
   ...
   call Func...(GetTriggerUnit...)
   call Func...(GetTriggerUnit...)
   call Func...(GetTriggerUnit...)
   ...
endfunction

function2 ..
   ...
   call Func...(GetTriggerUnit...)
   call Func...(GetTriggerUnit...)
   call Func...(GetTriggerUnit...)
   ...
endfunction

function3 ..
   ...
   call Func...(GetTriggerUnit...)
   call Func...(GetTriggerUnit...)
   call Func...(GetTriggerUnit...)
   ...
endfunction

function TestOptimize ...
call function1
call function2
call function3
endfunction

Optimized ???:
Code:
globals
 unit GetTriggerUnit0 = null
endglobals

function1 ..
   ...
   call Func...(GetTriggerUnit0...)
   call Func...(GetTriggerUnit0...)
   call Func...(GetTriggerUnit0...)
   ...
endfunction

function2 ..
   ...
   call Func...(GetTriggerUnit0...)
   call Func...(GetTriggerUnit0...)
   call Func...(GetTriggerUnit0...)
   ...
endfunction

function3 ..
   ...
   call Func...(GetTriggerUnit0...)
   call Func...(GetTriggerUnit0...)
   call Func...(GetTriggerUnit0...)
   ...
endfunction

function TestOptimize ...
set GetTriggerUnit0 = GetTriggerUnit( )
call function1
call function2
call function3
endfunction

This is optimization or no ? :D


15.05.2017: 1.3b version
= Bug fixes (fix some cases bad detecting leaks)



15.05.2017: 1.4a version
+ fix missing INIFileParser.dll file
+ added first optimization in code
+ added warning messages



After enable Leak fix and Optimize code, you need manually move changes from war3map_opt.j to your script. (Leak fix can be unitialize vars in very few cases)
 
Last edited:
Level 4
Joined
Jun 22, 2016
Messages
71
It would be great if it could scan the map's war3map.j file and print all the issues in the Command Prompt. Having all the logs recorded in separate log files can be time consuming.
 

eejin

Tool Moderator
Level 12
Joined
Mar 6, 2017
Messages
221
The tool does what it promises and the UI is simple and to the point. While it doesn't crash when using a map with VJass the output may not be entirely correct so this is something to keep in mind.

As the tool warns do not replace your war3map.j with the optimized output, but rather copy/move the optimizations by hand.

Adding VJass support and automatically extracting the war3map.j file from a map would be nice additions.

Approved!
 
Level 7
Joined
Jun 5, 2018
Messages
180
I would suggest the author to update the UI of this tool, since some overlaps between static text and the edit control occurred. An allignment of static text could be great. I use window 8 64bit.
1.png
In addition, add an icon to this tool please!
 
Level 25
Joined
Feb 2, 2006
Messages
1,667
This tool uses some interesting ideas. However, it would need improvement:
  • For example, add an option to exclude Blizzard's map script functions by default like the generated ones for unit drops or to create units/doodads etc. it should also excluded generated global variables, trigger functions for the unused detection etc.
  • The leak detection is an over approximation. I get that there is no other way. If I assign a local variable with FirstOfGroup and won't remove it, it is probably not a leak. You cannot detect leaks any other way but maybe rename it to something like "overapproximated leaks".
  • The optimizations: Should I REALLY store GetTriggerPlayer() in a local variable only because I used it 2 times. Are you sure it is that much faster? I would prefer some detection of too many nested loops or expressions which can be stored as constants or can at least be simplified. You could also analyze the number of periodic events/timers and the code which is called in those timer/trigger functions to warn about too much going on periodically. Another optimization could be to add more conditions to triggers which react to events for all units.
I guess the alternative would be to have some dynamic analysis at runtime.
 
Top