Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
![]() |
#1 | Link |
Registered User
Join Date: Jan 2012
Location: On the net
Posts: 76
|
AviSynth scripting language bug?
Has anyone noticed that if you call a function that throws an exception within a try block, all variables are wiped from the stack frame? I mean the entire stack frame is just gone, even in previous function scopes all the way to the top level. But if you throw an exception within the try block without creating another function scope, everything works fine.
Globals don't seem to be affected though. Here is an example: Code:
global output__junk = BlankClip(height=0, width=0, length=0) global output__filename = "output.log" function output(string s) { output__junk.WriteFileStart(output__filename, "s", append=true) return 1 } global g = "GLOBAL" l = "LOCAL" function fail { assert(false) } try { assert(false) } catch(e) {} try { output("g="+g) } catch(e) { output("g doesn't exist. "+e) } try { output("l="+l) } catch(e) { output("l doesn't exist. "+e) } try { fail } catch(e) {} try { output("g="+g) } catch(e) { output("g doesn't exist. "+e) } try { output("l="+l) } catch(e) { output("l doesn't exist. "+e) } l = "LOCAL" try { output("g="+g) } catch(e) { output("g doesn't exist. "+e) } try { output("l="+l) } catch(e) { output("l doesn't exist. "+e) } output("fn1") function fn1 { l1 = "LOCAL1" try { assert(false) } catch(e) {} try { output("g="+g) } catch(e) { output("g doesn't exist. "+e) } try { output("l1="+l1) } catch(e) { output("l1 doesn't exist. "+e) } } fn1 try { output("g="+g) } catch(e) { output("g doesn't exist. "+e) } try { output("l="+l) } catch(e) { output("l doesn't exist. "+e) } output("fn2") function fn2 { l1 = "LOCAL1" try { fail } catch(e) {} try { output("g="+g) } catch(e) { output("g doesn't exist. "+e) } try { output("l1="+l1) } catch(e) { output("l1 doesn't exist. "+e) } } fn2 try { output("g="+g) } catch(e) { output("g doesn't exist. "+e) } try { output("l="+l) } catch(e) { output("l doesn't exist. "+e) } Code:
g=GLOBAL l=LOCAL g=GLOBAL l doesn't exist. I don't know what "l" means (test.avs, line 23) g=GLOBAL l=LOCAL fn1 g=GLOBAL l1=LOCAL1 g=GLOBAL l=LOCAL fn2 g=GLOBAL l1 doesn't exist. I don't know what "l1" means (test.avs, line 49) g=GLOBAL l doesn't exist. I don't know what "l" means (test.avs, line 53) Strange bug, Mx Last edited by maxxon; 26th January 2012 at 09:52. Reason: Forgot to add another test case. |
![]() |
![]() |
![]() |
#2 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
Interesting...
What is happening is that when an exception causes a jump out of the failing function, its local scope is not being popped off the stack, so the local variables of the caller are still hidden. With this additional test case: Code:
function fail2 { l = "FAIL2" assert(false) } l = "LOCAL" try { fail2 } catch(e) {} try { output("g="+g) } catch(e) { output("g doesn't exist. "+e) } try { output("l="+l) } catch(e) { output("l doesn't exist. "+e) } Code:
g=GLOBAL l=FAIL2 Code:
AVSValue ScriptFunction::Execute(AVSValue args, void* user_data, IScriptEnvironment* env) { ScriptFunction* self = (ScriptFunction*)user_data; env->PushContext(); for (int i=0; i<args.ArraySize(); ++i) env->SetVar(self->param_names[i], args[i]); AVSValue result = self->body->Evaluate(env); env->PopContext(); return result; } |
![]() |
![]() |
![]() |
#3 | Link | ||
Registered User
Join Date: Jan 2012
Location: On the net
Posts: 76
|
Quote:
![]() Quote:
Code:
AVSValue ScriptFunction::Execute(AVSValue args, void* user_data, IScriptEnvironment* env) { ScriptFunction* self = (ScriptFunction*)user_data; env->PushContext(); try { for (int i=0; i<args.ArraySize(); ++i) env->SetVar(self->param_names[i], args[i]); AVSValue result = self->body->Evaluate(env); } catch (std::exception& e) { // reference, pointer, whatever is being used or whatever object base type is being used. env->PopContext(); throw e; } env->PopContext(); return result; } ![]() Mx Hmmm, this forum doesn't have the plugins for code highlighting enabled. ![]() |
||
![]() |
![]() |
![]() |
#4 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
It's part of the Avisynth parser/interpreter.
Quote:
Code:
catch (...) { env->PopContext(); throw; } |
|
![]() |
![]() |
![]() |
#5 | Link | ||
Registered User
Join Date: Jan 2012
Location: On the net
Posts: 76
|
Yeah, I figured that much.
![]() Quote:
Quote:
Mx |
||
![]() |
![]() |
![]() |
#6 | Link | ||
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
Quote:
![]() Quote:
|
||
![]() |
![]() |
![]() |
#8 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,430
|
Quote:
That's why writing control functions in the script language, using Eval() on a user-supplied code fragment, is not very useful, as any variables used have to be global. I was going to post something about that on your other thread once I had time to look properly at your library package. |
|
![]() |
![]() |
![]() |
#10 | Link | ||
Registered User
Join Date: Jan 2012
Location: On the net
Posts: 76
|
Quote:
Quote:
|\/|x |
||
![]() |
![]() |
![]() |
Tags |
avisynth script, bug, try catch |
Thread Tools | Search this Thread |
Display Modes | |
|
|