Bug 14163 - declared variable in window.eval statement not preserved after return from calling context
Summary: declared variable in window.eval statement not preserved after return from ca...
Status: RESOLVED WORKSFORME
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 523.x (Safari 3)
Hardware: All All
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
: 16677 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-06-15 05:22 PDT by qomo.team
Modified: 2012-09-06 16:46 PDT (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description qomo.team 2007-06-15 05:22:30 PDT
(This bug is reported as #4458636 to Apple Bug Reporter in Feb. 2006, but exists till now)

Webkit doesn't work correctly on the lifetime control of global variables declared explicitly in window.eval() method while calling from a function.
Those variables declared explicitly will be destoryed out of the caller function of window.eval().

The attached test.html shows the problem:
alert() in f() works fine, both test1 & test2 will popup, but only test1 will popup by alert() in the global context.
And if window.eval() is called in the global context, both places of alert() works fine.

Workaround:
Don't use var while declare global variables in eval()


test.html:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Testcase</title>
<script>
function f()
{
window.eval('test1=1', 'JavaScript');
window.eval('var test2=2', 'JavaScript');
alert(test1)
alert(test2);
}
f();
alert(test1)
alert(test2);
</script>
</head>
<body />
</html>
Comment 1 qomo.team 2007-06-15 05:38:35 PDT
well, the bug also exsists in Mozilla's JSRef, but can be passed by by using eval.call() or eval.apply() instead of window.eval().
Comment 2 qomo.team 2007-06-15 05:51:07 PDT
also declaration of functions, a simple test case:

window.eval('function test1() {}', 'JavaScript');
window.eval('test2 = new Function() {}', 'JavaScript');
alert(test1);
alert(test2);
Comment 3 David Kilzer (:ddkilzer) 2007-06-15 10:14:51 PDT
Thanks for the bug report!  Which version(s) of Safari and/or WebKit have you tested recently?  We're especially interested in Safari 3.0 beta as well as a Nightly WebKit build (http://nightly.webkit.org/).

Comment 4 David Kilzer (:ddkilzer) 2007-06-15 10:15:43 PDT
<rdar://problem/4458636>

Comment 5 qomo.team 2007-06-15 19:03:38 PDT
(In reply to comment #3)
> Thanks for the bug report!  Which version(s) of Safari and/or WebKit have you
> tested recently?  We're especially interested in Safari 3.0 beta as well as a
> Nightly WebKit build (http://nightly.webkit.org/).
> 

Test with Safari 2.0(419.3), Safari 3.0 Beta(502.10.1 for Mac & 502.11 for Win) and WebKit-SVN-r21955, all of them have this bug.
Comment 6 Mark Rowe (bdash) 2007-06-18 16:53:46 PDT
Is this a dupe of bug 11399?
Comment 7 qomo.team 2007-06-23 00:22:30 PDT
(In reply to comment #6)
> Is this a dupe of bug 11399?
> 

It's about the same thing(window.eval), but not a duplicate bug.

Bug #11399 means "calling context" is wrong, but we found that the variables are like to handled by a wrong way.
read through ECMA-262 sec. 10.2.2, variables declared in eval() context don't have a {DontDelete} property, but only what declared by "var " are deleted after.

As a ref: Our scripts sometimes need a way that declaring {DontDelete} variables in evaled codes, in Gecko's javascript engine, we use eval.apply().
Comment 8 Marcus Better 2007-10-15 05:08:44 PDT
(In reply to comment #2)
> also declaration of functions, a simple test case:
> 
> window.eval('function test1() {}', 'JavaScript');
> window.eval('test2 = new Function() {}', 'JavaScript');

This test case is flawed. The use of the Function constructor is illegal. It should be
  window.eval('test2 = new Function()');

In that case the result is that test1 will not be defined outside of f, but test2 will (confirmed with WebKit nightly build r26570).

Is a fix planned before Safari 3.0?
Comment 9 David Kilzer (:ddkilzer) 2007-10-15 20:24:33 PDT
(In reply to comment #8)
> (In reply to comment #2)
> > also declaration of functions, a simple test case:
> > 
> > window.eval('function test1() {}', 'JavaScript');
> > window.eval('test2 = new Function() {}', 'JavaScript');
> 
> This test case is flawed. The use of the Function constructor is illegal. It
> should be
>   window.eval('test2 = new Function()');
> 
> In that case the result is that test1 will not be defined outside of f, but
> test2 will (confirmed with WebKit nightly build r26570).

So are you saying this bug is already fixed with WebKit nightly build r26570?  What about r26359?

> Is a fix planned before Safari 3.0?

It depends on whether this bug is already fixed or not in r26359.
Comment 10 Geoffrey Garen 2007-10-22 13:34:06 PDT
It's hard to tell if this bug has been fixed or not.

If it hasn't, it blocks bug 14868 because we need to get the semantics of variable declaration correct before we can optimize it. `var' statements inside `eval' statements are a specifically interesting case that we need to get right.
Comment 11 Adam Roben (:aroben) 2007-10-22 15:14:45 PDT
(In reply to comment #10)
> It's hard to tell if this bug has been fixed or not.
> 
> If it hasn't, it blocks bug 14868 because we need to get the semantics of
> variable declaration correct before we can optimize it. `var' statements inside
> `eval' statements are a specifically interesting case that we need to get
> right.

I believe this is in fact working now. The Inspector is a nice testcase for this. Just type the following in the Console:

var a = "hi";<Enter>
a<Enter>

You will see the value "hi" printed. The Inspector uses window.eval for evaluation, so I think this works now.

Geoff, do you think this is correct?
Comment 12 qomo.team 2007-12-30 06:57:46 PST
There seems to be some kind of misunderstanding, take a look at the original test case:

function f()
{
window.eval('test1=1', 'JavaScript');
window.eval('var test2=2', 'JavaScript');
alert(test1);
alert(test2);
}
f();
---------
By declaring either with or without  "var", both of them is available in the
context of function f() (thus two alert dialog with "1" and "2" showed).
---------
alert(test1);
alert(test2);
---------
And then, after function f() ends, the test1 exsist, BUT test2 disappeared!
This is different from what IE's execScript() and Gecko's eval() with syntax "window.eval(script);" does.

(the other ways in Gecko such like "window.eval(script, lang);" "eval(script)" has the bug same as what described here, with even worse effects such as leading a crash. But they seems not going to resolve that, referenced as https://bugzilla.mozilla.org/show_bug.cgi?id=352045).

Comment 13 qomo.team 2007-12-30 06:57:58 PST
*** Bug 16677 has been marked as a duplicate of this bug. ***
Comment 14 Cameron Zwarich (cpst) 2008-06-07 02:10:43 PDT
This does not block bug 14868, because the variable lookup optimizations were landed long ago without resolving this.
Comment 15 Gavin Barraclough 2012-09-06 16:46:32 PDT
Test case appears to work in Safari 6.0 - all vars appear to be preserved.  Please reopen with more specific expected results if this still repros for you.