eliminate arbitrary size restrictions where possible
This commit is contained in:
parent
5c8d8942b1
commit
9fd9d81afe
35
chunk.h
35
chunk.h
@ -11,8 +11,7 @@
|
||||
* our needs. Most of the interesting changes happen in the compiler.
|
||||
*/
|
||||
typedef enum {
|
||||
OP_CONSTANT,
|
||||
OP_CONSTANT_LONG,
|
||||
OP_CONSTANT = 1,
|
||||
OP_NEGATE,
|
||||
OP_RETURN,
|
||||
OP_ADD,
|
||||
@ -30,42 +29,46 @@ typedef enum {
|
||||
OP_LESS,
|
||||
OP_PRINT,
|
||||
OP_DEFINE_GLOBAL,
|
||||
OP_DEFINE_GLOBAL_LONG,
|
||||
OP_GET_GLOBAL,
|
||||
OP_GET_GLOBAL_LONG,
|
||||
OP_SET_GLOBAL,
|
||||
OP_SET_GLOBAL_LONG,
|
||||
OP_SET_LOCAL,
|
||||
OP_SET_LOCAL_LONG,
|
||||
OP_GET_LOCAL,
|
||||
OP_GET_LOCAL_LONG,
|
||||
OP_JUMP_IF_FALSE,
|
||||
OP_JUMP_IF_TRUE,
|
||||
OP_JUMP,
|
||||
OP_LOOP,
|
||||
OP_CALL,
|
||||
OP_CLOSURE,
|
||||
OP_CLOSURE_LONG,
|
||||
OP_GET_UPVALUE,
|
||||
OP_GET_UPVALUE_LONG,
|
||||
OP_SET_UPVALUE,
|
||||
OP_SET_UPVALUE_LONG,
|
||||
OP_CLOSE_UPVALUE,
|
||||
OP_CLASS,
|
||||
OP_CLASS_LONG,
|
||||
OP_SET_PROPERTY,
|
||||
OP_SET_PROPERTY_LONG,
|
||||
OP_GET_PROPERTY,
|
||||
OP_GET_PROPERTY_LONG,
|
||||
OP_METHOD,
|
||||
OP_METHOD_LONG,
|
||||
OP_IMPORT,
|
||||
OP_IMPORT_LONG,
|
||||
OP_INHERIT,
|
||||
OP_GET_SUPER,
|
||||
OP_GET_SUPER_LONG,
|
||||
OP_PUSH_TRY,
|
||||
OP_RAISE,
|
||||
|
||||
OP_CONSTANT_LONG = 128,
|
||||
OP_PRINT_LONG,
|
||||
OP_DEFINE_GLOBAL_LONG,
|
||||
OP_GET_GLOBAL_LONG,
|
||||
OP_SET_GLOBAL_LONG,
|
||||
OP_SET_LOCAL_LONG,
|
||||
OP_GET_LOCAL_LONG,
|
||||
OP_CALL_LONG,
|
||||
OP_CLOSURE_LONG,
|
||||
OP_GET_UPVALUE_LONG,
|
||||
OP_SET_UPVALUE_LONG,
|
||||
OP_CLASS_LONG,
|
||||
OP_SET_PROPERTY_LONG,
|
||||
OP_GET_PROPERTY_LONG,
|
||||
OP_METHOD_LONG,
|
||||
OP_IMPORT_LONG,
|
||||
OP_GET_SUPER_LONG,
|
||||
} KrkOpCode;
|
||||
|
||||
/**
|
||||
|
49
compiler.c
49
compiler.c
@ -64,10 +64,12 @@ typedef struct Compiler {
|
||||
struct Compiler * enclosing;
|
||||
KrkFunction * function;
|
||||
FunctionType type;
|
||||
Local locals[MAX_LOCALS];
|
||||
size_t localCount;
|
||||
size_t scopeDepth;
|
||||
Upvalue upvalues[MAX_LOCALS];
|
||||
size_t localsSpace;
|
||||
Local * locals;
|
||||
size_t upvaluesSpace;
|
||||
Upvalue * upvalues;
|
||||
} Compiler;
|
||||
|
||||
typedef struct ClassCompiler {
|
||||
@ -94,6 +96,10 @@ static void initCompiler(Compiler * compiler, FunctionType type) {
|
||||
compiler->localCount = 0;
|
||||
compiler->scopeDepth = 0;
|
||||
compiler->function = krk_newFunction();
|
||||
compiler->localsSpace = 8;
|
||||
compiler->locals = GROW_ARRAY(Local,NULL,0,8);
|
||||
compiler->upvaluesSpace = 0;
|
||||
compiler->upvalues = NULL;
|
||||
current = compiler;
|
||||
|
||||
if (type != TYPE_MODULE) {
|
||||
@ -255,6 +261,11 @@ static KrkFunction * endCompiler() {
|
||||
return function;
|
||||
}
|
||||
|
||||
static void freeCompiler(Compiler * compiler) {
|
||||
FREE_ARRAY(Local,compiler->locals, compiler->localsSpace);
|
||||
FREE_ARRAY(Upvalue,compiler->upvalues, compiler->upvaluesSpace);
|
||||
}
|
||||
|
||||
static void endOfLine() {
|
||||
if (!(match(TOKEN_EOL) || match(TOKEN_EOF))) {
|
||||
errorAtCurrent("Expected end of line.");
|
||||
@ -380,8 +391,12 @@ static void varDeclaration() {
|
||||
}
|
||||
|
||||
static void printStatement() {
|
||||
expression();
|
||||
emitByte(OP_PRINT);
|
||||
int argCount = 0;
|
||||
do {
|
||||
expression();
|
||||
argCount++;
|
||||
} while (match(TOKEN_COMMA));
|
||||
EMIT_CONSTANT_OP(OP_PRINT, argCount);
|
||||
}
|
||||
|
||||
static void synchronize() {
|
||||
@ -499,10 +514,8 @@ static void function(FunctionType type, size_t blockWidth) {
|
||||
if (match(TOKEN_EQUAL)) {
|
||||
consume(TOKEN_NONE,"Optional arguments can only be assigned the default value of None.");
|
||||
current->function->defaultArgs++;
|
||||
if (current->function->defaultArgs > 255) errorAtCurrent("too many function parameters");
|
||||
} else {
|
||||
current->function->requiredArgs++;
|
||||
if (current->function->requiredArgs > 255) errorAtCurrent("too many function parameters");
|
||||
}
|
||||
} while (match(TOKEN_COMMA));
|
||||
}
|
||||
@ -518,8 +531,13 @@ static void function(FunctionType type, size_t blockWidth) {
|
||||
for (size_t i = 0; i < function->upvalueCount; ++i) {
|
||||
/* TODO: if the maximum count changes, fix the sizes for this */
|
||||
emitByte(compiler.upvalues[i].isLocal ? 1 : 0);
|
||||
emitByte(compiler.upvalues[i].index);
|
||||
if (i > 255) {
|
||||
emitByte((compiler.upvalues[i].index >> 16) & 0xFF);
|
||||
emitByte((compiler.upvalues[i].index >> 8) & 0xFF);
|
||||
}
|
||||
emitByte((compiler.upvalues[i].index) & 0xFF);
|
||||
}
|
||||
freeCompiler(&compiler);
|
||||
}
|
||||
|
||||
static void method(size_t blockWidth) {
|
||||
@ -1010,9 +1028,10 @@ static size_t addUpvalue(Compiler * compiler, ssize_t index, int isLocal) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (upvalueCount == MAX_LOCALS) {
|
||||
error("Too many closure variables in function.");
|
||||
return 0;
|
||||
if (upvalueCount + 1 > current->upvaluesSpace) {
|
||||
size_t old = current->upvaluesSpace;
|
||||
current->upvaluesSpace = GROW_CAPACITY(old);
|
||||
current->upvalues = GROW_ARRAY(Upvalue,current->upvalues,old,current->upvaluesSpace);
|
||||
}
|
||||
compiler->upvalues[upvalueCount].isLocal = isLocal;
|
||||
compiler->upvalues[upvalueCount].index = index;
|
||||
@ -1091,7 +1110,6 @@ static void list(int canAssign) {
|
||||
do {
|
||||
expression();
|
||||
/* TOKEN_FOR for comprehensions? */
|
||||
if (argCount == 255) error("Too many values in list expression.");
|
||||
argCount++;
|
||||
} while (match(TOKEN_COMMA));
|
||||
}
|
||||
@ -1211,9 +1229,10 @@ static ssize_t resolveLocal(Compiler * compiler, KrkToken * name) {
|
||||
}
|
||||
|
||||
static void addLocal(KrkToken name) {
|
||||
if (current->localCount == MAX_LOCALS) {
|
||||
error("too many locals");
|
||||
return;
|
||||
if (current->localCount + 1 > current->localsSpace) {
|
||||
size_t old = current->localsSpace;
|
||||
current->localsSpace = GROW_CAPACITY(old);
|
||||
current->locals = GROW_ARRAY(Local,current->locals,old,current->localsSpace);
|
||||
}
|
||||
Local * local = ¤t->locals[current->localCount++];
|
||||
local->name = name;
|
||||
@ -1256,7 +1275,6 @@ static uint8_t argumentList() {
|
||||
if (!check(TOKEN_RIGHT_PAREN)) {
|
||||
do {
|
||||
expression();
|
||||
if (argCount == 255) error("Too many arguments to function."); // Need long call...
|
||||
argCount++;
|
||||
} while (match(TOKEN_COMMA));
|
||||
}
|
||||
@ -1304,6 +1322,7 @@ KrkFunction * krk_compile(const char * src, int newScope, char * fileName) {
|
||||
}
|
||||
|
||||
KrkFunction * function = endCompiler();
|
||||
freeCompiler(&compiler);
|
||||
return parser.hadError ? NULL : function;
|
||||
}
|
||||
|
||||
|
18
debug.c
18
debug.c
@ -27,7 +27,7 @@ void krk_disassembleChunk(KrkChunk * chunk, const char * name) {
|
||||
#define OPERANDB(opc) case opc: { uint32_t operand = chunk->code[offset + 1]; \
|
||||
fprintf(stderr, "%-16s %4d\n", #opc, (int)operand); \
|
||||
return offset + 2; }
|
||||
#define OPERANDL(opc) OPERANDB(opc) \
|
||||
#define OPERAND(opc) OPERANDB(opc) \
|
||||
case opc ## _LONG: { uint32_t operand = (chunk->code[offset + 1] << 16) | \
|
||||
(chunk->code[offset + 2] << 8) | (chunk->code[offset + 3]); \
|
||||
fprintf(stderr, "%-16s %4d\n", #opc "_LONG", (int)operand); \
|
||||
@ -70,9 +70,10 @@ size_t krk_disassembleInstruction(KrkChunk * chunk, size_t offset) {
|
||||
SIMPLE(OP_EQUAL)
|
||||
SIMPLE(OP_GREATER)
|
||||
SIMPLE(OP_LESS)
|
||||
SIMPLE(OP_PRINT)
|
||||
SIMPLE(OP_POP)
|
||||
SIMPLE(OP_INHERIT)
|
||||
SIMPLE(OP_RAISE)
|
||||
SIMPLE(OP_CLOSE_UPVALUE)
|
||||
CONSTANT(OP_DEFINE_GLOBAL,(void)0)
|
||||
CONSTANT(OP_CONSTANT,(void)0)
|
||||
CONSTANT(OP_GET_GLOBAL,(void)0)
|
||||
@ -84,18 +85,17 @@ size_t krk_disassembleInstruction(KrkChunk * chunk, size_t offset) {
|
||||
CONSTANT(OP_CLOSURE, CLOSURE_MORE)
|
||||
CONSTANT(OP_IMPORT, (void)0)
|
||||
CONSTANT(OP_GET_SUPER, (void)0)
|
||||
OPERANDL(OP_SET_LOCAL)
|
||||
OPERANDL(OP_GET_LOCAL)
|
||||
OPERANDL(OP_SET_UPVALUE)
|
||||
OPERANDL(OP_GET_UPVALUE)
|
||||
OPERAND(OP_SET_LOCAL)
|
||||
OPERAND(OP_GET_LOCAL)
|
||||
OPERAND(OP_SET_UPVALUE)
|
||||
OPERAND(OP_GET_UPVALUE)
|
||||
OPERAND(OP_CALL)
|
||||
OPERAND(OP_PRINT)
|
||||
JUMP(OP_JUMP,+)
|
||||
JUMP(OP_JUMP_IF_FALSE,+)
|
||||
JUMP(OP_JUMP_IF_TRUE,+)
|
||||
JUMP(OP_LOOP,-)
|
||||
JUMP(OP_PUSH_TRY,+)
|
||||
SIMPLE(OP_RAISE)
|
||||
OPERANDB(OP_CALL)
|
||||
SIMPLE(OP_CLOSE_UPVALUE)
|
||||
default:
|
||||
fprintf(stderr, "Unknown opcode: %02x\n", opcode);
|
||||
return offset + 1;
|
||||
|
92
vm.c
92
vm.c
@ -729,21 +729,13 @@ static void addObjects() {
|
||||
#define READ_CONSTANT(s) (frame->closure->function->chunk.constants.values[readBytes(frame,s)])
|
||||
#define READ_STRING(s) AS_STRING(READ_CONSTANT(s))
|
||||
|
||||
static size_t readBytes(CallFrame * frame, int num) {
|
||||
if (num == 1) return READ_BYTE();
|
||||
else if (num == 2) {
|
||||
unsigned int top = READ_BYTE();
|
||||
unsigned int bot = READ_BYTE();
|
||||
return (top << 8) | (bot);
|
||||
} else if (num == 3) {
|
||||
unsigned int top = READ_BYTE();
|
||||
unsigned int mid = READ_BYTE();
|
||||
unsigned int bot = READ_BYTE();
|
||||
return (top << 16) | (mid << 8) | (bot);
|
||||
static inline size_t readBytes(CallFrame * frame, int num) {
|
||||
size_t out = READ_BYTE();
|
||||
while (--num) {
|
||||
out <<= 8;
|
||||
out |= (READ_BYTE() & 0xFF);
|
||||
}
|
||||
|
||||
krk_runtimeError("Invalid byte read?");
|
||||
return (size_t)-1;
|
||||
return out;
|
||||
}
|
||||
|
||||
static KrkClosure * boundNative(NativeFn method, int arity) {
|
||||
@ -764,8 +756,16 @@ static KrkClosure * boundNative(NativeFn method, int arity) {
|
||||
}
|
||||
|
||||
/* Call with these arguments */
|
||||
krk_writeChunk(&methodWrapper->chunk, OP_CALL, 1);
|
||||
krk_writeChunk(&methodWrapper->chunk, arity + 1, 1); /* arguments to call with */
|
||||
if (arity > 255) {
|
||||
int n = arity + 1;
|
||||
krk_writeChunk(&methodWrapper->chunk, OP_CALL_LONG, 1);
|
||||
krk_writeChunk(&methodWrapper->chunk, (n >> 16) & 0xFF, 1);
|
||||
krk_writeChunk(&methodWrapper->chunk, (n >> 8) & 0xFF, 1);
|
||||
krk_writeChunk(&methodWrapper->chunk, (n >> 0) & 0xFF, 1);
|
||||
} else {
|
||||
krk_writeChunk(&methodWrapper->chunk, OP_CALL, 1);
|
||||
krk_writeChunk(&methodWrapper->chunk, arity + 1, 1); /* arguments to call with */
|
||||
}
|
||||
|
||||
/* Return from the wrapper with whatever result we got from the native method */
|
||||
krk_writeChunk(&methodWrapper->chunk, OP_RETURN, 1);
|
||||
@ -898,15 +898,26 @@ static KrkValue run() {
|
||||
(size_t)(frame->ip - frame->closure->function->chunk.code));
|
||||
}
|
||||
#endif
|
||||
uint8_t opcode;
|
||||
switch ((opcode = READ_BYTE())) {
|
||||
uint8_t opcode = READ_BYTE();
|
||||
int operandWidth = (opcode & (1 << 7)) ? 3 : 1;
|
||||
|
||||
switch (opcode) {
|
||||
case OP_PRINT_LONG:
|
||||
case OP_PRINT: {
|
||||
if (!IS_STRING(krk_peek(0))) {
|
||||
krk_push(OBJECT_VAL(S("")));
|
||||
krk_swap();
|
||||
addObjects();
|
||||
uint32_t args = readBytes(frame, operandWidth);
|
||||
for (uint32_t i = 0; i < args; ++i) {
|
||||
KrkValue printable = krk_peek(args-i-1);
|
||||
if (!IS_STRING(printable)) {
|
||||
krk_push(OBJECT_VAL(S("")));
|
||||
krk_push(printable);
|
||||
addObjects();
|
||||
printable = krk_pop();
|
||||
}
|
||||
fprintf(stdout, "%s%s", AS_CSTRING(printable), (i == args - 1) ? "\n" : " ");
|
||||
}
|
||||
for (uint32_t i = 0; i < args; ++i) {
|
||||
krk_pop();
|
||||
}
|
||||
fprintf(stdout, "%s\n", AS_CSTRING(krk_pop()));
|
||||
break;
|
||||
}
|
||||
case OP_RETURN: {
|
||||
@ -950,7 +961,7 @@ static KrkValue run() {
|
||||
}
|
||||
case OP_CONSTANT_LONG:
|
||||
case OP_CONSTANT: {
|
||||
size_t index = readBytes(frame, opcode == OP_CONSTANT ? 1 : 3);
|
||||
size_t index = readBytes(frame, operandWidth);
|
||||
KrkValue constant = frame->closure->function->chunk.constants.values[index];
|
||||
krk_push(constant);
|
||||
break;
|
||||
@ -962,14 +973,14 @@ static KrkValue run() {
|
||||
case OP_POP: krk_pop(); break;
|
||||
case OP_DEFINE_GLOBAL_LONG:
|
||||
case OP_DEFINE_GLOBAL: {
|
||||
KrkString * name = READ_STRING((opcode == OP_DEFINE_GLOBAL ? 1 : 3));
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
krk_tableSet(&vm.globals, OBJECT_VAL(name), krk_peek(0));
|
||||
krk_pop();
|
||||
break;
|
||||
}
|
||||
case OP_GET_GLOBAL_LONG:
|
||||
case OP_GET_GLOBAL: {
|
||||
KrkString * name = READ_STRING((opcode == OP_GET_GLOBAL ? 1 : 3));
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
KrkValue value;
|
||||
if (!krk_tableGet(&vm.globals, OBJECT_VAL(name), &value)) {
|
||||
krk_runtimeError("Undefined variable '%s'.", name->chars);
|
||||
@ -980,7 +991,7 @@ static KrkValue run() {
|
||||
}
|
||||
case OP_SET_GLOBAL_LONG:
|
||||
case OP_SET_GLOBAL: {
|
||||
KrkString * name = READ_STRING((opcode == OP_SET_GLOBAL ? 1 : 3));
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
if (krk_tableSet(&vm.globals, OBJECT_VAL(name), krk_peek(0))) {
|
||||
krk_tableDelete(&vm.globals, OBJECT_VAL(name));
|
||||
/* TODO: This should probably just work as an assignment? */
|
||||
@ -991,7 +1002,7 @@ static KrkValue run() {
|
||||
}
|
||||
case OP_IMPORT_LONG:
|
||||
case OP_IMPORT: {
|
||||
KrkString * name = READ_STRING((opcode == OP_IMPORT ? 1 : 3));
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
KrkValue module;
|
||||
if (!krk_tableGet(&vm.modules, OBJECT_VAL(name), &module)) {
|
||||
/* Try to open it */
|
||||
@ -1014,13 +1025,13 @@ static KrkValue run() {
|
||||
}
|
||||
case OP_GET_LOCAL_LONG:
|
||||
case OP_GET_LOCAL: {
|
||||
uint32_t slot = readBytes(frame, (opcode == OP_GET_LOCAL ? 1 : 3));
|
||||
uint32_t slot = readBytes(frame, operandWidth);
|
||||
krk_push(vm.stack[frame->slots + slot]);
|
||||
break;
|
||||
}
|
||||
case OP_SET_LOCAL_LONG:
|
||||
case OP_SET_LOCAL: {
|
||||
uint32_t slot = readBytes(frame, (opcode == OP_SET_LOCAL ? 1 : 3));
|
||||
uint32_t slot = readBytes(frame, operandWidth);
|
||||
vm.stack[frame->slots + slot] = krk_peek(0);
|
||||
break;
|
||||
}
|
||||
@ -1054,8 +1065,9 @@ static KrkValue run() {
|
||||
vm.flags |= KRK_HAS_EXCEPTION;
|
||||
goto _finishException;
|
||||
}
|
||||
case OP_CALL_LONG:
|
||||
case OP_CALL: {
|
||||
int argCount = READ_BYTE();
|
||||
int argCount = readBytes(frame, operandWidth);
|
||||
if (!callValue(krk_peek(argCount), argCount)) {
|
||||
if (vm.flags & KRK_HAS_EXCEPTION) goto _finishException;
|
||||
return NONE_VAL();
|
||||
@ -1065,12 +1077,12 @@ static KrkValue run() {
|
||||
}
|
||||
case OP_CLOSURE_LONG:
|
||||
case OP_CLOSURE: {
|
||||
KrkFunction * function = AS_FUNCTION(READ_CONSTANT((opcode == OP_CLOSURE ? 1 : 3)));
|
||||
KrkFunction * function = AS_FUNCTION(READ_CONSTANT(operandWidth));
|
||||
KrkClosure * closure = krk_newClosure(function);
|
||||
krk_push(OBJECT_VAL(closure));
|
||||
for (size_t i = 0; i < closure->upvalueCount; ++i) {
|
||||
int isLocal = READ_BYTE();
|
||||
int index = READ_BYTE();
|
||||
int index = readBytes(frame,(i > 255) ? 3 : 1);
|
||||
if (isLocal) {
|
||||
closure->upvalues[i] = captureUpvalue(frame->slots + index);
|
||||
} else {
|
||||
@ -1081,13 +1093,13 @@ static KrkValue run() {
|
||||
}
|
||||
case OP_GET_UPVALUE_LONG:
|
||||
case OP_GET_UPVALUE: {
|
||||
int slot = readBytes(frame, (opcode == OP_GET_UPVALUE) ? 1 : 3);
|
||||
int slot = readBytes(frame, operandWidth);
|
||||
krk_push(*UPVALUE_LOCATION(frame->closure->upvalues[slot]));
|
||||
break;
|
||||
}
|
||||
case OP_SET_UPVALUE_LONG:
|
||||
case OP_SET_UPVALUE: {
|
||||
int slot = readBytes(frame, (opcode == OP_SET_UPVALUE) ? 1 : 3);
|
||||
int slot = readBytes(frame, operandWidth);
|
||||
*UPVALUE_LOCATION(frame->closure->upvalues[slot]) = krk_peek(0);
|
||||
break;
|
||||
}
|
||||
@ -1097,7 +1109,7 @@ static KrkValue run() {
|
||||
break;
|
||||
case OP_CLASS_LONG:
|
||||
case OP_CLASS: {
|
||||
KrkString * name = READ_STRING((opcode == OP_CLASS ? 1 : 3));
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
KrkClass * _class = krk_newClass(name);
|
||||
_class->filename = frame->closure->function->chunk.filename;
|
||||
krk_tableAddAll(&vm.object_class->methods, &_class->methods);
|
||||
@ -1106,7 +1118,7 @@ static KrkValue run() {
|
||||
}
|
||||
case OP_GET_PROPERTY_LONG:
|
||||
case OP_GET_PROPERTY: {
|
||||
KrkString * name = READ_STRING((opcode == OP_GET_PROPERTY ? 1 : 3));
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
switch (krk_peek(0).type) {
|
||||
case VAL_OBJECT:
|
||||
switch (OBJECT_TYPE(krk_peek(0))) {
|
||||
@ -1196,7 +1208,7 @@ _undefined:
|
||||
goto _finishException;
|
||||
}
|
||||
KrkInstance * instance = AS_INSTANCE(krk_peek(1));
|
||||
KrkString * name = READ_STRING((opcode == OP_SET_PROPERTY ? 1 : 3));
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
krk_tableSet(&instance->fields, OBJECT_VAL(name), krk_peek(0));
|
||||
KrkValue value = krk_pop();
|
||||
krk_pop(); /* instance */
|
||||
@ -1205,7 +1217,7 @@ _undefined:
|
||||
}
|
||||
case OP_METHOD_LONG:
|
||||
case OP_METHOD: {
|
||||
defineMethod(READ_STRING((opcode == OP_METHOD ? 1 : 3)));
|
||||
defineMethod(READ_STRING(operandWidth));
|
||||
break;
|
||||
}
|
||||
case OP_INHERIT: {
|
||||
@ -1221,7 +1233,7 @@ _undefined:
|
||||
}
|
||||
case OP_GET_SUPER_LONG:
|
||||
case OP_GET_SUPER: {
|
||||
KrkString * name = READ_STRING((opcode == OP_GET_SUPER ? 1 : 3));
|
||||
KrkString * name = READ_STRING(operandWidth);
|
||||
KrkClass * superclass = AS_CLASS(krk_pop());
|
||||
if (!bindMethod(superclass, name)) {
|
||||
return NONE_VAL();
|
||||
|
Loading…
Reference in New Issue
Block a user