private void EmitRegExpInit(ClassFileWriter cfw)
{
// precompile all regexp literals
int totalRegCount = 0;
for (int i = 0; i != scriptOrFnNodes.Length; ++i)
{
totalRegCount += scriptOrFnNodes[i].GetRegexpCount();
}
if (totalRegCount == 0)
{
return;
}
cfw.StartMethod(REGEXP_INIT_METHOD_NAME, REGEXP_INIT_METHOD_SIGNATURE, (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE));
cfw.AddField("_reInitDone", "Z", (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE | ClassFileWriter.ACC_VOLATILE));
cfw.Add(ByteCode.GETSTATIC, mainClassName, "_reInitDone", "Z");
int doInit = cfw.AcquireLabel();
cfw.Add(ByteCode.IFEQ, doInit);
cfw.Add(ByteCode.RETURN);
cfw.MarkLabel(doInit);
// get regexp proxy and store it in local slot 1
cfw.AddALoad(0);
// context
cfw.AddInvoke(ByteCode.INVOKESTATIC, "org/mozilla/javascript/ScriptRuntime", "checkRegExpProxy", "(Lorg/mozilla/javascript/Context;" + ")Lorg/mozilla/javascript/RegExpProxy;");
cfw.AddAStore(1);
// proxy
// We could apply double-checked locking here but concurrency
// shouldn't be a problem in practice
for (int i_1 = 0; i_1 != scriptOrFnNodes.Length; ++i_1)
{
ScriptNode n = scriptOrFnNodes[i_1];
int regCount = n.GetRegexpCount();
for (int j = 0; j != regCount; ++j)
{
string reFieldName = GetCompiledRegexpName(n, j);
string reFieldType = "Ljava/lang/Object;";
string reString = n.GetRegexpString(j);
string reFlags = n.GetRegexpFlags(j);
cfw.AddField(reFieldName, reFieldType, (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE));
cfw.AddALoad(1);
// proxy
cfw.AddALoad(0);
// context
cfw.AddPush(reString);
if (reFlags == null)
{
cfw.Add(ByteCode.ACONST_NULL);
}
else
{
cfw.AddPush(reFlags);
}
cfw.AddInvoke(ByteCode.INVOKEINTERFACE, "org/mozilla/javascript/RegExpProxy", "compileRegExp", "(Lorg/mozilla/javascript/Context;" + "Ljava/lang/String;Ljava/lang/String;" + ")Ljava/lang/Object;");
cfw.Add(ByteCode.PUTSTATIC, mainClassName, reFieldName, reFieldType);
}
}
cfw.AddPush(1);
cfw.Add(ByteCode.PUTSTATIC, mainClassName, "_reInitDone", "Z");
cfw.Add(ByteCode.RETURN);
cfw.StopMethod((short)2);
}