diff --git a/packages/beize_shared/lib/bytecode/chunk.dart b/packages/beize_shared/lib/bytecode/chunk.dart index a290f7b..19ea8f7 100644 --- a/packages/beize_shared/lib/bytecode/chunk.dart +++ b/packages/beize_shared/lib/bytecode/chunk.dart @@ -32,7 +32,9 @@ class BeizeChunk { } int codeAt(final int index) => codes[index]; + BeizeOpCodes opCodeAt(final int index) => BeizeOpCodes.values[codeAt(index)]; + int lineAt(final int index) => lines[index]; BeizeSerializedConstant serialize() => [moduleIndex, codes, lines]; diff --git a/packages/beize_shared/lib/bytecode/constants/program.dart b/packages/beize_shared/lib/bytecode/constants/program.dart index 57ce2f5..67975bb 100644 --- a/packages/beize_shared/lib/bytecode/constants/program.dart +++ b/packages/beize_shared/lib/bytecode/constants/program.dart @@ -3,7 +3,6 @@ import 'function.dart'; class BeizeProgramConstant { const BeizeProgramConstant({ - // required this.moduleNames, required this.modules, required this.constants, }); @@ -13,13 +12,6 @@ class BeizeProgramConstant { ) => BeizeProgramConstant( modules: (serialized[0] as List).cast(), - // modules: (serialized[1] as List) - // .map( - // (final dynamic x) => BeizeFunctionConstant.deserialize( - // x as BeizeSerializedConstant, - // ), - // ) - // .toList(), constants: (serialized[1] as List).map((final dynamic x) { if (x is List) { return BeizeFunctionConstant.deserialize(x); @@ -28,11 +20,14 @@ class BeizeProgramConstant { }).toList(), ); - // final List moduleNames; final List modules; final List constants; - int moduleAt(final int index) => modules[index]; + String moduleNameAt(final int index) => constantAt(modules[index]) as String; + + BeizeFunctionConstant moduleFunctionAt(final int index) => + constantAt(modules[index + 1]) as BeizeFunctionConstant; + BeizeConstant constantAt(final int index) => constants[index]; BeizeSerializedConstant serialize() => [ diff --git a/packages/beize_vm/lib/vm/call_frame.dart b/packages/beize_vm/lib/vm/call_frame.dart index 8d25cc4..700b05b 100644 --- a/packages/beize_vm/lib/vm/call_frame.dart +++ b/packages/beize_vm/lib/vm/call_frame.dart @@ -110,8 +110,8 @@ class BeizeCallFrame { vm.program.constantAt(function.chunk.codeAt(index)); String toStackTraceLine(final int depth) { - final int nameIndex = vm.program.modules[function.chunk.moduleIndex]; - final String moduleName = vm.program.constantAt(nameIndex) as String; + final String moduleName = + vm.program.moduleNameAt(function.chunk.moduleIndex); final int line = function.chunk.lineAt(sip); return '#$depth $moduleName at line $line'; } diff --git a/packages/beize_vm/lib/vm/interpreter.dart b/packages/beize_vm/lib/vm/interpreter.dart index 8d06764..f0dfcb8 100644 --- a/packages/beize_vm/lib/vm/interpreter.dart +++ b/packages/beize_vm/lib/vm/interpreter.dart @@ -497,16 +497,21 @@ class BeizeInterpreter { case BeizeOpCodes.opImport: final int moduleIndex = chunk.codeAt(frame.ip); final int asIndex = chunk.codeAt(frame.ip + 1); - final String name = frame.readConstantAt(asIndex) as String; + final String name = frame.vm.program.constantAt(asIndex) as String; frame.ip += 2; - final BeizePreparedModule module = frame.vm.prepareModule( - moduleIndex, - isEntrypoint: false, - ); - namespace.declare(name, module.value); - final BeizeInterpreterResult result = frame.vm.loadModule(module); - if (result.isFailure) { - return handleException(result.error); + final BeizeModuleValue? pValue = frame.vm.lookupModule(moduleIndex); + if (pValue != null) { + namespace.declare(name, pValue); + } else { + final BeizePreparedModule module = frame.vm.prepareModule( + moduleIndex, + isEntrypoint: false, + ); + namespace.declare(name, module.value); + final BeizeInterpreterResult result = frame.vm.loadModule(module); + if (result.isFailure) { + return handleException(result.error); + } } break; diff --git a/packages/beize_vm/lib/vm/vm.dart b/packages/beize_vm/lib/vm/vm.dart index d17d4db..f15f441 100644 --- a/packages/beize_vm/lib/vm/vm.dart +++ b/packages/beize_vm/lib/vm/vm.dart @@ -37,7 +37,7 @@ class BeizeVM { final BeizeVMOptions options; final BeizeNamespace globalNamespace = BeizeNamespace.withNatives(); - final Map modules = {}; + final Map modules = {}; late final BeizeCallFrame topFrame; Future run() async { @@ -51,22 +51,24 @@ class BeizeVM { } } + BeizeModuleValue? lookupModule(final int moduleIndex) => modules[moduleIndex]; + BeizePreparedModule prepareModule( final int moduleIndex, { required final bool isEntrypoint, }) { - final int nameIndex = program.moduleAt(moduleIndex); - final String moduleName = program.constantAt(nameIndex) as String; final BeizeNamespace namespace = globalNamespace.enclosed; final BeizeModuleValue value = BeizeModuleValue(namespace); - modules[moduleName] = value; + modules[moduleIndex] = value; final BeizeCallFrame frame = BeizeCallFrame( vm: this, - function: program.constantAt(nameIndex + 1) as BeizeFunctionConstant, + function: program.moduleFunctionAt(moduleIndex), namespace: namespace, parent: !isEntrypoint ? topFrame : null, ); - if (isEntrypoint) topFrame = frame; + if (isEntrypoint) { + topFrame = frame; + } return BeizePreparedModule( moduleIndex: moduleIndex, frame: frame,