What is the instruction count?

533 views
Skip to first unread message

Joshua England

unread,
Oct 19, 2011, 5:41:48 AM10/19/11
to mozilla-rhino
Hi,

We're testing how to integrate JS Rhino into our webapp in order to
allow customers to write custom server-side code. Because this will be
outside the control of developers, we need to run the scripts in a
sandbox. However, during testing we hit a problem on instruction
counts.

It seemed that 2 calls to the function below counted for roughly 5000
instructions each.

function setIfNotEquals(ref, amount) {
var str = inter.getValue(ref);
var val = parseInt(str);
if (val != amount) {
inter.setValue(ref, amount);
inter.throwError(ref, "Not equal);
}
}

inter is an interface into the rest of the webapp (i.e. a Java Object)
and ref is a database reference.

My questions are:
- What does Rhino use to calculate its instruction count? Is its the
number of JavaScript instructions, JVM instructions or something else?
- Do library calls count towards the instruction count? i.e. does
parseInt() and inter.setValue() increase the count
- Where can I find documentation about instruction counts?

Sorry to be asking this here, but the API reference (http://
www.mozilla.org/rhino/apidocs/) seems to be down and I haven't found
an answer in the documentation or from searching the web.

Thank you in advance :)

- Josh

Joshua England

unread,
Oct 19, 2011, 5:42:34 AM10/19/11
to mozilla-rhino
Oh I forgot to add we're using 1.7R2

felipe valdez

unread,
Oct 19, 2011, 10:56:35 AM10/19/11
to mozill...@googlegroups.com
what about code.split(/(\n|;)/).length ?


On Wed, Oct 19, 2011 at 4:42 AM, Joshua England <joshua....@clicktools.com> wrote:
Oh I forgot to add we're using 1.7R2



--
312-444-2124
Skype: f3l.headhunter
Casa: 8043901



Mark Storer

unread,
Oct 19, 2011, 2:28:54 PM10/19/11
to mozill...@googlegroups.com
Do you really want to count this as one instruction?

    var foo = someFunc( anotherFunc(bar), (baz ? qux : quux), yetAnotherFunc());

You'll get a good general ballpark with EOL/semicolon counting, but there's lots of things preventing it from being precise.


--Mark Storer
  Professional Geek

felipe valdez

unread,
Oct 19, 2011, 3:45:33 PM10/19/11
to mozill...@googlegroups.com
the reality is, you can't limit it.

think of this:


eval(decrypt("askldjajsdalsdjlasdjalsjdlakjsd");

millions of isntructions, inside a single line.

your safest bet is possibly lines/bytes

but still, if they want to go beyond the limit, they could do this:

eval(ungzip("..."))

so you'll probably have to disbale eval() as well.

just my $ 0.02


Joshua England

unread,
Oct 20, 2011, 4:13:23 AM10/20/11
to mozilla-rhino
well the intension is to stop stuff like never ending loops or deep
recursion aswell as preventing access to the wider system (i.e.
stopping the importing of java classes).
The recursion can be stopped through a stack depth level but the
instructions is a wierder thing.

So its unclear what contributes to the instruction count? And its
pretty hard to limit the overall instruction count anyway ?

How would you suggest we should implement governor limits i.e. like
APEX execution on force.com ?

thanks

- Josh

On Oct 19, 8:45 pm, felipe valdez <felipeval...@gmail.com> wrote:
> the reality is, you can't limit it.
>
> think of this:
>
> eval(decrypt("askldjajsdalsdjlasdjalsjdlakjsd");
>
> millions of isntructions, inside a single line.
>
> your safest bet is possibly lines/bytes
>
> but still, if they want to go beyond the limit, they could do this:
>
> eval(ungzip("..."))
>
> so you'll probably have to disbale eval() as well.
>
> just my $ 0.02
>
>
>
>
>
>
>
>
>
> On Wed, Oct 19, 2011 at 1:28 PM, Mark Storer <mstorer3...@gmail.com> wrote:
> > Do you really want to count this as one instruction?
>
> >     var foo = someFunc( anotherFunc(bar), (baz ? qux : quux),
> > yetAnotherFunc());
>
> > You'll get a good general ballpark with EOL/semicolon counting, but there's
> > lots of things preventing it from being precise.
>
> > --Mark Storer
> >   Professional Geek
>

Joshua England

unread,
Oct 20, 2011, 7:06:53 AM10/20/11
to mozilla-rhino
SOLUTION:

By default Rhino treats all function calls and 'new' calls as 100
instructions. This means that a single line of code can look like many
many more instructions. For example:

function parsedate(str) {
str_split = str.split("-"); // 100 instructions
year = parseInt(str_split[0]); // 100
month = parseInt(str_split[1]); // 100
day = parseInt(str_split[2]); // 100
return new Date(year, month, day); // 100 for new 100 for Date() so
200
}

parsedate("2011-08-20"); // 100 for entering function + 600 for
function execution. Total cost: 700 instructions.


For 'library' functions not much can be done, but when it comes to
your own code you can add a weighting. For example:

// Your libary code
void jsFunction_foo() {
..
Context cx = Context.getCurrentContext();
MyContext mcx = (MyContext) cx;
mcx.add(2000); // custom instruction count for this method
}

// Observer
observeInstructionCount(Context cx, int i) {
int extra = ((MyContext) cx).total();
extra += i;
if (i + cx.totalInstructions() > LIMIT) {
throw Error();
}
}

On Oct 20, 9:13 am, Joshua England <joshua.engl...@clicktools.com>
wrote:

felipe valdez

unread,
Oct 20, 2011, 11:14:03 AM10/20/11
to mozill...@googlegroups.com
google does this:

set a timeout for maximum time of execution, this limits the cpu, which is probably the resource  you want to limit.

also, they limit storage, api calls, emails sent, hours used of cpu per day, etc.

Reply all
Reply to author
Forward
0 new messages