mirror of
https://github.com/Sei-Lisa/LSL-PyOptimizer
synced 2025-07-01 07:38:21 +00:00
Remove "magic names" where possible, using new data from fndata.txt
This commit is contained in:
parent
b80b157489
commit
70f39d7f5e
6 changed files with 50 additions and 58 deletions
|
@ -20,16 +20,6 @@
|
||||||
import lslfuncs
|
import lslfuncs
|
||||||
|
|
||||||
class deadcode(object):
|
class deadcode(object):
|
||||||
# Functions that cause the rest of the current block to never be executed
|
|
||||||
# e.g. default { state_entry() { llResetScript(); llSetPos(<3,3,3>); } }
|
|
||||||
# in that example, llSetPos is dead code because llResetScript does not let
|
|
||||||
# it execute. llRemoveInventory(llGetScriptName()), llDetachFromAvatar()
|
|
||||||
# and llDie() come close, but evidence shows that it's not the case and the
|
|
||||||
# script can execute some more lines before stopping.
|
|
||||||
# llScriptState(..., FALSE) allows resuming after it, so whatever comes
|
|
||||||
# next isn't really dead code.
|
|
||||||
# TODO: check if there are any more than this one.
|
|
||||||
TerminatorFuncs = ('llResetScript',)
|
|
||||||
|
|
||||||
def MarkReferences(self, node):
|
def MarkReferences(self, node):
|
||||||
"""Marks each node it passes through as executed (X), and each variable
|
"""Marks each node it passes through as executed (X), and each variable
|
||||||
|
@ -185,7 +175,7 @@ class deadcode(object):
|
||||||
self.MarkReferences(self.tree[sym['Loc']])
|
self.MarkReferences(self.tree[sym['Loc']])
|
||||||
node['X'] = self.tree[sym['Loc']]['X']
|
node['X'] = self.tree[sym['Loc']]['X']
|
||||||
else:
|
else:
|
||||||
node['X'] = node['name'] not in self.TerminatorFuncs
|
node['X'] = 'stop' not in sym
|
||||||
# Note that JUMP analysis is incomplete. To do it correctly, we
|
# Note that JUMP analysis is incomplete. To do it correctly, we
|
||||||
# should follow the jump right to its destination, in order to know
|
# should follow the jump right to its destination, in order to know
|
||||||
# if that branch leads to a RETURN or completely stops the event.
|
# if that branch leads to a RETURN or completely stops the event.
|
||||||
|
|
|
@ -23,16 +23,12 @@ from lslbasefuncs import ELSLCantCompute, fi,ff,fs,fk,v2f,q2f,fl, \
|
||||||
TOUCH_INVALID_TEXCOORD, cond
|
TOUCH_INVALID_TEXCOORD, cond
|
||||||
ff, q2f # keep pyflakes happy as these are not used
|
ff, q2f # keep pyflakes happy as these are not used
|
||||||
|
|
||||||
TouchEvents = ('touch', 'touch_start', 'touch_end')
|
GetEnvSettings = frozenset(('agent_limit', 'dynamic_pathfinding', 'estate_id',
|
||||||
DetectionEvents = ('touch', 'touch_start', 'touch_end',
|
|
||||||
'collision', 'collision_start', 'collision_end',
|
|
||||||
'sensor')
|
|
||||||
GetEnvSettings = ('agent_limit', 'dynamic_pathfinding', 'estate_id',
|
|
||||||
'estate_name', 'frame_number', 'region_cpu_ratio', 'region_idle',
|
'estate_name', 'frame_number', 'region_cpu_ratio', 'region_idle',
|
||||||
'region_product_name', 'region_product_sku', 'region_start_time',
|
'region_product_name', 'region_product_sku', 'region_start_time',
|
||||||
'sim_channel', 'sim_version', 'simulator_hostname',
|
'sim_channel', 'sim_version', 'simulator_hostname',
|
||||||
'region_max_prims', # <http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_RC_Magnum/16#16.11.02.321369>
|
'region_max_prims', # <http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_RC_Magnum/16#16.11.02.321369>
|
||||||
'region_object_bonus') # <http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_RC_Magnum/16#16.12.03.322072>
|
'region_object_bonus')) # <http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_RC_Magnum/16#16.12.03.322072>
|
||||||
|
|
||||||
xp_error_messages = {
|
xp_error_messages = {
|
||||||
-1:u'unknown error id',
|
-1:u'unknown error id',
|
||||||
|
@ -68,111 +64,111 @@ def llClearLinkMedia(link, face):
|
||||||
return 0
|
return 0
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
|
|
||||||
def llDetectedGrab(idx, event=None):
|
def llDetectedGrab(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event == 'touch' or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'grab' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_VECTOR
|
return ZERO_VECTOR
|
||||||
|
|
||||||
def llDetectedGroup(idx, event=None):
|
def llDetectedGroup(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def llDetectedKey(idx, event=None):
|
def llDetectedKey(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return Key(NULL_KEY)
|
return Key(NULL_KEY)
|
||||||
|
|
||||||
def llDetectedLinkNumber(idx, event=None):
|
def llDetectedLinkNumber(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def llDetectedName(idx, event=None):
|
def llDetectedName(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return NULL_KEY
|
return NULL_KEY
|
||||||
|
|
||||||
def llDetectedOwner(idx, event=None):
|
def llDetectedOwner(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return Key(NULL_KEY)
|
return Key(NULL_KEY)
|
||||||
|
|
||||||
def llDetectedPos(idx, event=None):
|
def llDetectedPos(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_VECTOR
|
return ZERO_VECTOR
|
||||||
|
|
||||||
def llDetectedRot(idx, event=None):
|
def llDetectedRot(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_ROTATION
|
return ZERO_ROTATION
|
||||||
|
|
||||||
def llDetectedTouchBinormal(idx, event=None):
|
def llDetectedTouchBinormal(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in TouchEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'touch' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_VECTOR
|
return ZERO_VECTOR
|
||||||
|
|
||||||
def llDetectedTouchFace(idx, event=None):
|
def llDetectedTouchFace(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in TouchEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'touch' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return -1 if event in DetectionEvents and 0 <= idx <= 15 else 0
|
return -1 if 'detect' in evsym and 0 <= idx <= 15 else 0
|
||||||
|
|
||||||
def llDetectedTouchNormal(idx, event=None):
|
def llDetectedTouchNormal(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in TouchEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'touch' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_VECTOR
|
return ZERO_VECTOR
|
||||||
|
|
||||||
def llDetectedTouchPos(idx, event=None):
|
def llDetectedTouchPos(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in TouchEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'touch' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_VECTOR
|
return ZERO_VECTOR
|
||||||
|
|
||||||
def llDetectedTouchST(idx, event=None):
|
def llDetectedTouchST(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event is None or event in DetectionEvents):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
# In detection events that are not touch events, it returns
|
# In detection events that are not touch events, it returns
|
||||||
# TOUCH_INVALID_TEXCOORD if idx < num, else ZERO_VECTOR,
|
# TOUCH_INVALID_TEXCOORD if idx < num, else ZERO_VECTOR,
|
||||||
# but we only know that num >= 1.
|
# but we only know that num >= 1.
|
||||||
if idx == 0 and event is not None and event not in TouchEvents:
|
if idx == 0 and evsym is not None and 'touch' not in evsym:
|
||||||
# index 0 always exists, so we know the result
|
# index 0 always exists, so we know the result
|
||||||
return TOUCH_INVALID_TEXCOORD
|
return TOUCH_INVALID_TEXCOORD
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_VECTOR
|
return ZERO_VECTOR
|
||||||
|
|
||||||
def llDetectedTouchUV(idx, event=None):
|
def llDetectedTouchUV(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event is None or event in DetectionEvents):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
# In detection events that are not touch events, it returns
|
# In detection events that are not touch events, it returns
|
||||||
# TOUCH_INVALID_TEXCOORD if idx < num, else ZERO_VECTOR,
|
# TOUCH_INVALID_TEXCOORD if idx < num, else ZERO_VECTOR,
|
||||||
# but we only know that num >= 1.
|
# but we only know that num >= 1.
|
||||||
if idx == 0 and event is not None and event not in TouchEvents:
|
if idx == 0 and evsym is not None and 'touch' not in evsym:
|
||||||
# index 0 always exists, so we know the result
|
# index 0 always exists, so we know the result
|
||||||
return TOUCH_INVALID_TEXCOORD
|
return TOUCH_INVALID_TEXCOORD
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_VECTOR
|
return ZERO_VECTOR
|
||||||
|
|
||||||
def llDetectedType(idx, event=None):
|
def llDetectedType(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def llDetectedVel(idx, event=None):
|
def llDetectedVel(idx, evsym=None):
|
||||||
idx = fi(idx)
|
idx = fi(idx)
|
||||||
if 0 <= idx <= 15 and (event in DetectionEvents or event is None):
|
if 0 <= idx <= 15 and (evsym is None or 'detect' in evsym):
|
||||||
raise ELSLCantCompute
|
raise ELSLCantCompute
|
||||||
return ZERO_VECTOR
|
return ZERO_VECTOR
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ class foldconst(object):
|
||||||
return # Nothing to do if it's already simplified.
|
return # Nothing to do if it's already simplified.
|
||||||
child = node['ch'] if 'ch' in node else None
|
child = node['ch'] if 'ch' in node else None
|
||||||
|
|
||||||
if nt == 'FNCALL' and node['name'] == 'llStringLength':
|
if nt == 'FNCALL' and 'strlen' in self.symtab[0][node['name']]:
|
||||||
# llStringLength(expr) -> !(expr == "")
|
# llStringLength(expr) -> !(expr == "")
|
||||||
node = {'nt':'==', 't':'integer',
|
node = {'nt':'==', 't':'integer',
|
||||||
'ch':[child[0],
|
'ch':[child[0],
|
||||||
|
@ -1427,8 +1427,10 @@ class foldconst(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# May raise ELSLCantCompute
|
# May raise ELSLCantCompute
|
||||||
if name[:10] == 'llDetected':
|
if 'detect' in self.symtab[0][name]:
|
||||||
value = fn(*args, event=self.CurEvent)
|
value = fn(*args,
|
||||||
|
evsym=None if self.CurEvent is None
|
||||||
|
else self.events[self.CurEvent])
|
||||||
else:
|
else:
|
||||||
value = fn(*args)
|
value = fn(*args)
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -99,3 +99,6 @@ class optimizer(foldconst, renamer, deadcode, lastpass):
|
||||||
del self.tree
|
del self.tree
|
||||||
del self.symtab
|
del self.symtab
|
||||||
return treesymtab
|
return treesymtab
|
||||||
|
|
||||||
|
def __init__(self, lib):
|
||||||
|
self.events = lib[0]
|
||||||
|
|
2
main.py
2
main.py
|
@ -662,7 +662,7 @@ def main(argv):
|
||||||
return 1
|
return 1
|
||||||
del p, script
|
del p, script
|
||||||
|
|
||||||
opt = optimizer()
|
opt = optimizer(lib)
|
||||||
ts = opt.optimize(ts, options)
|
ts = opt.optimize(ts, options)
|
||||||
del opt
|
del opt
|
||||||
|
|
||||||
|
|
|
@ -248,8 +248,9 @@ class Test02_Parser(UnitTestCase):
|
||||||
|
|
||||||
class Test03_Optimizer(UnitTestCase):
|
class Test03_Optimizer(UnitTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.parser = parser(lslloadlib.LoadLibrary())
|
lib = lslloadlib.LoadLibrary()
|
||||||
self.opt = optimizer()
|
self.parser = parser(lib)
|
||||||
|
self.opt = optimizer(lib)
|
||||||
self.outscript = outscript()
|
self.outscript = outscript()
|
||||||
|
|
||||||
def test_coverage(self):
|
def test_coverage(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue