public AddField ( string fieldName, string type, short flags ) : void | ||
fieldName | string | the name of the field |
type | string | the type of the field using ... |
flags | short | /// the attributes of the field, such as ACC_PUBLIC, etc. /// bitwise or'd together /// |
return | void |
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); }
private void EmitConstantDudeInitializers(ClassFileWriter cfw) { int N = itsConstantListSize; if (N == 0) { return; } cfw.StartMethod("<clinit>", "()V", (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_FINAL)); double[] array = itsConstantList; for (int i = 0; i != N; ++i) { double num = array[i]; string constantName = "_k" + i; string constantType = GetStaticConstantWrapperType(num); cfw.AddField(constantName, constantType, (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE)); int inum = (int)num; if (inum == num) { cfw.AddPush(inum); cfw.AddInvoke(ByteCode.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); } else { cfw.AddPush(num); AddDoubleWrap(cfw); } cfw.Add(ByteCode.PUTSTATIC, mainClassName, constantName, constantType); } cfw.Add(ByteCode.RETURN); cfw.StopMethod((short)0); }
private byte[] GenerateCode(string encodedSource) { bool hasScript = (scriptOrFnNodes[0].GetType() == Token.SCRIPT); bool hasFunctions = (scriptOrFnNodes.Length > 1 || !hasScript); string sourceFile = null; if (compilerEnv.IsGenerateDebugInfo()) { sourceFile = scriptOrFnNodes[0].GetSourceName(); } ClassFileWriter cfw = new ClassFileWriter(mainClassName, SUPER_CLASS_NAME, sourceFile); cfw.AddField(ID_FIELD_NAME, "I", ClassFileWriter.ACC_PRIVATE); if (hasFunctions) { GenerateFunctionConstructor(cfw); } if (hasScript) { cfw.AddInterface("org/mozilla/javascript/Script"); GenerateScriptCtor(cfw); GenerateMain(cfw); GenerateExecute(cfw); } GenerateCallMethod(cfw); GenerateResumeGenerator(cfw); GenerateNativeFunctionOverrides(cfw, encodedSource); int count = scriptOrFnNodes.Length; for (int i = 0; i != count; ++i) { ScriptNode n = scriptOrFnNodes[i]; BodyCodegen bodygen = new BodyCodegen(); bodygen.cfw = cfw; bodygen.codegen = this; bodygen.compilerEnv = compilerEnv; bodygen.scriptOrFn = n; bodygen.scriptOrFnIndex = i; try { bodygen.GenerateBodyCode(); } catch (ClassFileWriter.ClassFileFormatException e) { throw ReportClassFileFormatException(n, e.Message); } if (n.GetType() == Token.FUNCTION) { OptFunctionNode ofn = OptFunctionNode.Get(n); GenerateFunctionInit(cfw, ofn); if (ofn.IsTargetOfDirectCall()) { EmitDirectConstructor(cfw, ofn); } } } EmitRegExpInit(cfw); EmitConstantDudeInitializers(cfw); return cfw.ToByteArray(); }