-/* vm/jit/parse.c - parser for JavaVM to intermediate code translation
+/* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
Changes: Carolyn Oates
Edwin Steiner
Joseph Wenninger
+ Christian Thalinger
- $Id: parse.c 1971 2005-03-01 20:06:36Z carolyn $
+ $Id: parse.c 2272 2005-04-11 15:49:51Z twisti $
*/
#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/global.h"
+#include "vm/linker.h"
#include "vm/loader.h"
+#include "vm/resolve.h"
#include "vm/options.h"
#include "vm/statistics.h"
#include "vm/stringlocal.h"
#include "vm/tables.h"
+#include "vm/jit/asmpart.h"
#include "vm/jit/jit.h"
#include "vm/jit/parse.h"
#include "vm/jit/inline/parseRT.h"
#define debug_writebranch if (DEBUG2==true) printf("op:: %s i: %d label_index[i]: %d label_index=0x%p\n",opcode_names[opcode], i, label_index[i], (void *)label_index);
#define debug_writebranch1
-
-/* function descriptor2typesL ***************************************************
-
- decodes a already checked method descriptor. The parameter count, the
- return type and the argument types are stored in the passed methodinfo.
- gets and saves classptr for object ref.s
-
-*******************************************************************************/
-
-classSetNode *descriptor2typesL(methodinfo *m)
-{
- int debugInfo = 0;
- int i;
- u1 *types, *tptr;
- int pcount, c;
- char *utf_ptr;
- classinfo** classtypes;
- char *class;
- char *desc;
- classSetNode *p=NULL;
- if (debugInfo >= 1) {
- printf("In descriptor2typesL >>>\t"); fflush(stdout);
- utf_display(m->class->name); printf(".");
- method_display(m);fflush(stdout);
- }
-
- pcount = 0;
- desc = MNEW (char, 256);
- types = DMNEW (u1, m->descriptor->blength);
- classtypes = MNEW (classinfo*, m->descriptor->blength+1);
- m->returnclass = NULL;
- tptr = types;
- if (!(m->flags & ACC_STATIC)) {
- *tptr++ = TYPE_ADR;
- if (debugInfo >= 1) {
- printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
- }
- classtypes[pcount] = m->class;
- p = addClassCone(p, m->class);
- pcount++;
- }
-
- utf_ptr = m->descriptor->text + 1;
- strcpy (desc,utf_ptr);
-
- while ((c = *desc++) != ')') {
- pcount++;
- switch (c) {
- case 'B':
- case 'C':
- case 'I':
- case 'S':
- case 'Z': *tptr++ = TYPE_INT;
- break;
- case 'J': *tptr++ = TYPE_LNG;
- break;
- case 'F': *tptr++ = TYPE_FLT;
- break;
- case 'D': *tptr++ = TYPE_DBL;
- break;
- case 'L': *tptr++ = TYPE_ADR;
- /* get class string */
- class = strtok(desc,";");
- desc = strtok(NULL,"\0");
- /* get/save classinfo ptr */
- classtypes[pcount-1] = class_get(utf_new_char(class));
- p = addClassCone(p, class_get(utf_new_char(class)));
- if (debugInfo >= 1) {
- printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
- printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
- utf_display(classtypes[pcount-1]->name);
- }
- break;
- case '[': *tptr++ = TYPE_ADR;
- while (c == '[')
- c = *desc++;
- /* get class string */
- if (c == 'L') {
- class = strtok(desc,";");
- desc = strtok(NULL,"\0");
- /* get/save classinfo ptr */
- classtypes[pcount-1] = class_get(utf_new_char(class));
- p= addClassCone(p, class_get(utf_new_char(class)));
- if (debugInfo >= 1) {
- printf("[Param#%i 's class type is: %s\n",pcount-1,class);
- printf("[classtypes[%i]=",pcount-1);fflush(stdout);
- utf_display(classtypes[pcount-1]->name);
- printf("\n");
- }
- }
- else
- classtypes[pcount-1] = NULL;
- break;
- default:
- panic("Ill formed methodtype-descriptor");
- }
- }
-
- /* compute return type */
- switch (*desc++) {
- case 'B':
- case 'C':
- case 'I':
- case 'S':
- case 'Z': m->returntype = TYPE_INT;
- break;
- case 'J': m->returntype = TYPE_LNG;
- break;
- case 'F': m->returntype = TYPE_FLT;
- break;
- case 'D': m->returntype = TYPE_DBL;
- break;
- case '[':
- m->returntype = TYPE_ADR;
- c = *desc;
- while (c == '[') {
- c = *desc++;
- }
- if (c != 'L') break;
- c = *desc;
- if (c == 'L')
- *(desc++);
- case 'L':
- m->returntype = TYPE_ADR;
-
- /* get class string */
- class = strtok(desc,";");
- m->returnclass = class_get(utf_new_char(class));
- if (m->returnclass == NULL) {
- printf("class=<%s>\t",class); fflush(stdout);
- panic ("return class not found");
- }
- break;
- case 'V': m->returntype = TYPE_VOID;
- break;
-
- default: panic("Ill formed methodtype-descriptor-ReturnType");
- }
-
- m->paramcount = pcount;
- m->paramtypes = types;
- m->paramclass = classtypes;
-
- if (debugInfo >=1) {
- if (pcount > 0) {
- for (i=0; i< m->paramcount; i++) {
- if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
- printf("Param #%i is:\t",i);
- utf_display(m->paramclass[i]->name);
- printf("\n");
- }
- }
- }
- if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) {
- printf("\tReturn Type is:\t"); fflush(stdout);
- utf_display(m->returnclass->name);
- printf("\n");
- }
-
- printf("params2types: START results in a set \n");
- printf("param2types: A Set size=%i=\n",sizeOfSet(p));
- printSet(p);
- }
-
- return p;
-}
-
-
-
-/* function descriptor2types ***************************************************
-
- decodes a already checked method descriptor. The parameter count, the
- return type and the argument types are stored in the passed methodinfo.
-
-*******************************************************************************/
-
-void descriptor2types(methodinfo *m)
-{
- u1 *types, *tptr;
- int pcount, c;
- char *utf_ptr;
- pcount = 0;
- types = DMNEW(u1, m->descriptor->blength);
-
- tptr = types;
- if (!(m->flags & ACC_STATIC)) {
- *tptr++ = TYPE_ADR;
- pcount++;
- }
-
- utf_ptr = m->descriptor->text + 1;
-
- while ((c = *utf_ptr++) != ')') {
- pcount++;
- switch (c) {
- case 'B':
- case 'C':
- case 'I':
- case 'S':
- case 'Z':
- *tptr++ = TYPE_INT;
- break;
- case 'J':
- *tptr++ = TYPE_LNG;
- break;
- case 'F':
- *tptr++ = TYPE_FLT;
- break;
- case 'D':
- *tptr++ = TYPE_DBL;
- break;
- case 'L':
- *tptr++ = TYPE_ADR;
- while (*utf_ptr++ != ';');
- break;
- case '[':
- *tptr++ = TYPE_ADR;
- while (c == '[')
- c = *utf_ptr++;
- if (c == 'L')
- while (*utf_ptr++ != ';') /* skip */;
- break;
- default:
- panic("Ill formed methodtype-descriptor");
- }
- }
-
- /* compute return type */
-
- switch (*utf_ptr++) {
- case 'B':
- case 'C':
- case 'I':
- case 'S':
- case 'Z':
- m->returntype = TYPE_INT;
- break;
- case 'J':
- m->returntype = TYPE_LNG;
- break;
- case 'F':
- m->returntype = TYPE_FLT;
- break;
- case 'D':
- m->returntype = TYPE_DBL;
- break;
- case '[':
- case 'L':
- m->returntype = TYPE_ADR;
- break;
- case 'V':
- m->returntype = TYPE_VOID;
- break;
- default:
- panic("Ill formed methodtype-descriptor");
- }
-
- m->paramcount = pcount;
- m->paramtypes = types;
-}
-
-
-
/*******************************************************************************
function 'parse' scans the JavaVM code and generates intermediate code
pushconstantitem:
if (i >= inline_env->method->class->cpcount)
- panic ("Attempt to access constant outside range");
+ error("Attempt to access constant outside range: %d >= %d", i, inline_env->method->class->cpcount);
switch (inline_env->method->class->cptags[i]) {
case CONSTANT_Integer:
OP(ICMD_CHECKASIZE);
i = code_get_u2(p + 1,inline_env->method);
{
- classinfo *component =
- (classinfo *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+ classinfo *component;
+ constant_classref *compr;
+ constant_classref *cr;
+ classinfo *c;
+
+#if defined(__X86_64__)
+ compr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+
+ if (!(cr = class_get_classref_multiarray_of(1, compr)))
+ return NULL;
- if (!class_load(component))
+ if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &c))
return NULL;
- if (!class_link(component))
+ if (c) {
+ LOADCONST_A_BUILTIN(c->vftbl);
+ BUILTIN2(BUILTIN_newarray, TYPE_ADR, currentline);
+
+ } else {
+ LOADCONST_A_BUILTIN(cr);
+ BUILTIN2(asm_BUILTIN_newarray, TYPE_ADR, currentline);
+ }
+ s_count++;
+#else
+ cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+
+ if (!resolve_classref(inline_env->method,
+ cr,resolveEager,true,&component))
return NULL;
- LOADCONST_A_BUILTIN(class_array_of(component)->vftbl);
-/* LOADCONST_A_BUILTIN(component); */
+ c = class_array_of(component,true);
+ if (!c)
+ return NULL;
+ LOADCONST_A_BUILTIN(c->vftbl);
s_count++;
BUILTIN2(BUILTIN_newarray, TYPE_ADR, currentline);
+#endif
}
OP(ICMD_CHECKEXCEPTION);
break;
case JAVA_MULTIANEWARRAY:
inline_env->method->isleafmethod = false;
- i = code_get_u2(p + 1,inline_env->method);
+ i = code_get_u2(p + 1, inline_env->method);
{
+ classinfo *component;
+ classinfo *c;
+ constant_classref *cr;
vftbl_t *arrayvftbl;
- s4 v = code_get_u1(p + 3,inline_env->method);
+ s4 v = code_get_u1(p + 3, inline_env->method);
-
+#if defined(__X86_64__)
+ cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+
+ if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &c))
+ return NULL;
+
+ if (c) {
+ OP2AT(opcode, v, c->vftbl, BUILTIN_nmultianewarray, currentline);
+
+ } else {
+ OP2AT(opcode, v, cr, asm_BUILTIN_multianewarray, currentline);
+ }
+#else
/* vftbl *arrayvftbl = */
/* ((classinfo *) class_getconstant(class, i, CONSTANT_Class))->vftbl; */
/* OP2A(opcode, v, arrayvftbl,currentline); */
- classinfo *component =
- (classinfo *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+ cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
- if (!class_load(component))
- return NULL;
-
- if (!class_link(component))
+ if (!resolve_classref_or_classinfo(inline_env->method,
+ CLASSREF_OR_CLASSINFO(cr),resolveEager,true,&component))
return NULL;
arrayvftbl = component->vftbl;
/* classinfo *arrayclass = */
/* (classinfo *) class_getconstant(class, i, CONSTANT_Class); */
/* OP2A(opcode, v, arrayclass, currentline); */
+#endif
}
break;
/* check if the lookup table is sorted correctly */
- if (i && (j <= prevvalue))
- panic("invalid LOOKUPSWITCH: table not sorted");
+ if (i && (j <= prevvalue)) {
+ *exceptionptr = new_verifyerror(m, "Unsorted lookup switch");
+ return NULL;
+ }
prevvalue = j;
/* target */
BUILTIN3(BUILTIN_aastore, TYPE_VOID, currentline);
break;
- case JAVA_PUTSTATIC:
case JAVA_GETSTATIC:
- i = code_get_u2(p + 1,inline_env->method);
+ case JAVA_PUTSTATIC:
+#if defined(__X86_64__)
+ case JAVA_GETFIELD:
+ case JAVA_PUTFIELD:
+#endif
+ i = code_get_u2(p + 1, inline_env->method);
{
- constant_FMIref *fr;
- fieldinfo *fi;
+ constant_FMIref *fr;
+ unresolved_field *uf;
+ fieldinfo *fi;
+ classinfo *c;
fr = class_getconstant(inline_env->method->class, i, CONSTANT_Fieldref);
+#if defined(__X86_64__)
+ OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
- if (!class_load(fr->class))
+ if (!(uf = create_unresolved_field(inline_env->method->class,
+ inline_env->method,
+ iptr,
+ NULL)))
return NULL;
- if (!class_link(fr->class))
+ /* store unresolved_field pointer */
+
+ iptr->target = uf;
+
+ /* only with -noverify, otherwise the typechecker does this */
+
+ if (!opt_verify) {
+ if (!resolve_field(uf, resolveLazy, &fi))
+ return NULL;
+
+ iptr->val.a = fi;
+ }
+ PINC;
+#else
+ {
+ classinfo *frclass;
+ if (!resolve_classref(inline_env->method,fr->classref,resolveEager,true,&frclass))
return NULL;
- fi = class_resolvefield(fr->class,
+ fi = class_resolvefield(frclass,
fr->name,
fr->descriptor,
inline_env->method->class,
if (!fi->class->initialized) {
inline_env->method->isleafmethod = false;
}
+ }
+#endif
}
break;
+#if !defined(__X86_64__)
case JAVA_PUTFIELD:
case JAVA_GETFIELD:
i = code_get_u2(p + 1,inline_env->method);
{
constant_FMIref *fr;
fieldinfo *fi;
+ classinfo *frclass;
fr = class_getconstant(inline_env->method->class, i, CONSTANT_Fieldref);
-
- if (!class_load(fr->class))
- return NULL;
-
- if (!class_link(fr->class))
+ if (!resolve_classref(inline_env->method,fr->classref,resolveEager,true,&frclass))
return NULL;
- fi = class_resolvefield(fr->class,
+ fi = class_resolvefield(frclass,
fr->name,
fr->descriptor,
inline_env->method->class,
OP2A(opcode, fi->type, fi, currentline);
}
break;
+#endif
/* method invocation *****/
case JAVA_INVOKESTATIC:
- i = code_get_u2(p + 1,inline_env->method);
+ i = code_get_u2(p + 1, inline_env->method);
{
constant_FMIref *mr;
methodinfo *mi;
-
+ unresolved_method *um;
+ classinfo *mrclass;
+
inline_env->method->isleafmethod = false;
mr = class_getconstant(inline_env->method->class, i, CONSTANT_Methodref);
+#if defined(__X86_64__)
+ OP2A_NOINC(opcode, mr->parseddesc.md->paramcount, mr, currentline);
+
+ um = create_unresolved_method(inline_env->method->class,
+ inline_env->method,
+ iptr,
+ NULL);
- if (!class_load(mr->class))
+ if (!um)
return NULL;
- if (!class_link(mr->class))
+ /* store the unresolved_method pointer */
+
+ iptr->target = um;
+
+ /* only with -noverify, otherwise the typechecker does this */
+
+ if (!opt_verify) {
+ if (!resolve_method(um, resolveLazy, &mi))
+ return NULL;
+
+ iptr->val.a = mi;
+ }
+ PINC;
+#else
+ if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
return NULL;
- mi = class_resolveclassmethod(mr->class,
+ mi = class_resolveclassmethod(mrclass,
mr->name,
mr->descriptor,
inline_env->method->class,
if (DEBUG4==true) {
method_display_w_class(mi);
- printf("\tINVOKE STATIC\n");
+ printf("\tINVOKE STAT\n");
fflush(stdout);}
if (!(mi->flags & ACC_STATIC)) {
return NULL;
}
- descriptor2types(mi);
+ method_descriptor2types(mi);
OP2A(opcode, mi->paramcount, mi, currentline);
+#endif
}
break;
case JAVA_INVOKESPECIAL:
case JAVA_INVOKEVIRTUAL:
- i = code_get_u2(p + 1,inline_env->method);
+ i = code_get_u2(p + 1, inline_env->method);
{
constant_FMIref *mr;
methodinfo *mi;
+ unresolved_method *um;
+ classinfo *mrclass;
inline_env->method->isleafmethod = false;
mr = class_getconstant(inline_env->method->class, i, CONSTANT_Methodref);
+#if defined(__X86_64__)
+ OP2A_NOINC(opcode, mr->parseddesc.md->paramcount + 1, mr, currentline);
+
+ um = create_unresolved_method(inline_env->method->class,
+ inline_env->method,
+ iptr,
+ NULL);
- if (!class_load(mr->class))
+ if (!um)
return NULL;
- if (!class_link(mr->class))
+ /* store the unresolved_method* */
+
+ iptr->target = um;
+
+ /* only with -noverify, otherwise the typechecker does this */
+
+ if (!opt_verify) {
+ if (!resolve_method(um, resolveLazy, &mi))
+ return NULL;
+
+ iptr->val.a = mi;
+ }
+ PINC;
+#else
+ if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
return NULL;
- mi = class_resolveclassmethod(mr->class,
+ mi = class_resolveclassmethod(mrclass,
mr->name,
mr->descriptor,
inline_env->method->class,
return NULL;
}
- descriptor2types(mi);
+ method_descriptor2types(mi);
OP2A(opcode, mi->paramcount, mi, currentline);
+#endif
}
break;
{
constant_FMIref *mr;
methodinfo *mi;
+ classinfo *mrclass;
+ unresolved_method *um;
inline_env->method->isleafmethod = false;
mr = class_getconstant(inline_env->method->class, i, CONSTANT_InterfaceMethodref);
+#if defined(__X86_64__)
+ OP2A_NOINC(opcode, mr->parseddesc.md->paramcount + 1, mr, currentline);
+
+ um = create_unresolved_method(inline_env->method->class,
+ inline_env->method,
+ iptr,
+ NULL);
- if (!class_load(mr->class))
+ if (!um)
return NULL;
- if (!class_link(mr->class))
+ /* store the unresolved_method* */
+
+ iptr->target = um;
+
+ /* only with -noverify, otherwise the typechecker does this */
+
+ if (!opt_verify) {
+ if (!resolve_method(um, resolveLazy, &mi))
+ return NULL;
+
+ iptr->val.a = mi;
+ }
+ PINC;
+#else
+ if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
return NULL;
- mi = class_resolveinterfacemethod(mr->class,
+ mi = class_resolveinterfacemethod(mrclass,
mr->name,
mr->descriptor,
inline_env->method->class,
method_display_w_class(mi);
printf("\tINVOKE INTERFACE\n");
fflush(stdout);}
- descriptor2types(mi);
+
+ method_descriptor2types(mi);
OP2A(opcode, mi->paramcount, mi, currentline);
+#endif
}
break;
/* miscellaneous object operations *******/
case JAVA_NEW:
- i = code_get_u2(p + 1,inline_env->method);
- LOADCONST_A_BUILTIN(class_getconstant(inline_env->method->class, i, CONSTANT_Class));
- s_count++;
- BUILTIN1(BUILTIN_new, TYPE_ADR, currentline);
- OP(ICMD_CHECKEXCEPTION);
+ {
+ constant_classref *cr;
+ classinfo *cls;
+
+#if defined(__X86_64__)
+ i = code_get_u2(p + 1, inline_env->method);
+ cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+
+ if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &cls))
+ return NULL;
+
+ /* <clinit> can throw an exception over native code */
+
+ if (cls && cls->initialized) {
+ LOADCONST_A_BUILTIN(cls);
+ BUILTIN1(BUILTIN_new, TYPE_ADR, currentline);
+
+ } else {
+ LOADCONST_A_BUILTIN(cr);
+ BUILTIN1((functionptr) asm_builtin_new, TYPE_ADR, currentline);
+ }
+
+ s_count++;
+ OP(ICMD_CHECKEXCEPTION);
+#else
+ i = code_get_u2(p + 1,inline_env->method);
+ cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+ if (!resolve_classref(inline_env->method,cr,resolveEager,true,&cls))
+ return NULL;
+ LOADCONST_A_BUILTIN(cls);
+ s_count++;
+ BUILTIN1(BUILTIN_new, TYPE_ADR, currentline);
+ OP(ICMD_CHECKEXCEPTION);
+#endif
+ }
break;
case JAVA_CHECKCAST:
- i = code_get_u2(p + 1,inline_env->method);
+ i = code_get_u2(p + 1, inline_env->method);
{
- classinfo *cls =
- (classinfo *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+ constant_classref *cr;
+ classinfo *cls;
+
+ cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
- if (!cls->loaded)
- if (!class_load(cls))
- return NULL;
+#if defined(__X86_64__)
+ if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &cls))
+ return NULL;
- if (!cls->linked)
- if (!class_link(cls))
+ if (cr->name->text[0] == '[') {
+ if (!resolve_classref(inline_env->method, cr, resolveEager, true, &cls))
return NULL;
+ /* array type cast-check */
+ LOADCONST_A_BUILTIN(cls->vftbl);
+ s_count++;
+ BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR, currentline);
+
+ } else {
+ /* object type cast-check */
+ OP2AT(opcode, 1, cls, cr, currentline);
+ }
+#else
+ if (!resolve_classref(inline_env->method,
+ cr,resolveEager,true,&cls))
+ return NULL;
+
if (cls->vftbl->arraydesc) {
/* array type cast-check */
LOADCONST_A_BUILTIN(cls->vftbl);
+ */
OP2A(opcode, 1, cls, currentline);
}
+#endif
}
break;
case JAVA_INSTANCEOF:
i = code_get_u2(p + 1,inline_env->method);
{
- classinfo *cls =
- (classinfo *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
+ constant_classref *cr;
+ classinfo *cls;
+
+ cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
- if (!cls->loaded)
- if (!class_load(cls))
- return NULL;
+#if defined(__X86_64__)
+ if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &cls))
+ return NULL;
- if (!cls->linked)
- if (!class_link(cls))
+ if (cr->name->text[0] == '[') {
+ if (!resolve_classref(inline_env->method, cr, resolveEager, true, &cls))
return NULL;
+ /* array type cast-check */
+ LOADCONST_A_BUILTIN(cls->vftbl);
+ s_count++;
+ BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT, currentline);
+
+ } else {
+ /* object type cast-check */
+ OP2AT(opcode, 1, cls, cr, currentline);
+ }
+#else
+ if (!resolve_classref(inline_env->method,
+ cr,resolveEager,true,&cls))
+ return NULL;
+
if (cls->vftbl->arraydesc) {
/* array type cast-check */
LOADCONST_A_BUILTIN(cls->vftbl);
+ */
OP2A(opcode, 1, cls, currentline);
}
+#endif
}
break;