From 6612cf2bd989f17959d0c8a8c4afe100a8aa0498 Mon Sep 17 00:00:00 2001 From: Blair McGlashan Date: Sat, 16 May 2020 20:32:36 +0100 Subject: [PATCH] Add C implementation of primitiveReturnInstVar Contributes to #531 --- Core/DolphinVM/IntPrim.cpp | 2 -- Core/DolphinVM/byteasm.asm | 51 -------------------------------------- Core/DolphinVM/bytecde.cpp | 46 ++++++++++++++++++++++++++++++++++ Core/DolphinVM/ist.h | 2 ++ 4 files changed, 48 insertions(+), 53 deletions(-) diff --git a/Core/DolphinVM/IntPrim.cpp b/Core/DolphinVM/IntPrim.cpp index afed049bc6..8475746fa4 100644 --- a/Core/DolphinVM/IntPrim.cpp +++ b/Core/DolphinVM/IntPrim.cpp @@ -9,8 +9,6 @@ #include "Interprt.h" #include "InterprtPrim.inl" -#define OOPSIZE 4 - Oop* __fastcall Interpreter::primitiveEqual(Oop* const sp, primargcount_t) { Oop arg = *sp; diff --git a/Core/DolphinVM/byteasm.asm b/Core/DolphinVM/byteasm.asm index d80d7d8632..168bddfa2c 100644 --- a/Core/DolphinVM/byteasm.asm +++ b/Core/DolphinVM/byteasm.asm @@ -4365,57 +4365,6 @@ ENDPRIMITIVE primitiveActivateMethod ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -BEGINPRIMITIVE primitiveReturnInstVar - ; Its a primitive return of an instance variable - ; Compiler should not generate such a method for a SmallInteger - ; Which inst var do we want? Well its that whose index is - ; in the extra index field of the method (normally used - ; for primitives) - ; 1 Nop - ; 2 PushInstVarN - ; 3(inst var index) - ; 4 ReturnStackTop - - mov ecx, [NEWMETHOD] - - ASSUME edx:NOTHING ; Don't need the argument count - - ; We need a mini interpreter now to extract the inst var index from the byte codes - - mov ecx, (OTE PTR[ecx]).m_location - ASSUME ecx:PTR CompiledCodeObj ; ECX points at the new method - - mov edx, [STEPPING] - mov eax, [ecx].m_byteCodes ; Get bytecodes into eax - note that it MUST be a SmallInteger - mov ecx, [_SP] ; ecx = receiver Oop at stack top - ASSUME ecx:PTR OTE - - test edx, edx - jnz stepping - - shr eax, 16 - mov edx, [ecx].m_location ; edx points at receiver object - ASSUME edx:PTR Object - and eax, 0FFh - - ; No arguments to pop as compiler only generates this quick method form if zero args - - ; Load inst var Oop from object into edx - mov edx, [edx].fields[eax*OOPSIZE] - ASSUME edx:Oop - - mov [_SP], edx ; Overwrite receiver with inst. var Oop - - mov eax, _SP ; primitiveSuccess(0) - ret - -stepping: - ; Fail so can step into method - mov eax, SMALLINTZERO - ret - -ENDPRIMITIVE primitiveReturnInstVar - BEGINPRIMITIVE primitiveSetInstVar ; Its a primitive set of an instance variable ; Compiler should not generate such a method for a SmallInteger diff --git a/Core/DolphinVM/bytecde.cpp b/Core/DolphinVM/bytecde.cpp index a22739f642..b0884dfad4 100755 --- a/Core/DolphinVM/bytecde.cpp +++ b/Core/DolphinVM/bytecde.cpp @@ -93,6 +93,35 @@ __declspec(naked) Oop* __fastcall Interpreter::primitiveReturnStaticZero(Oop* co ret } } + +__declspec(naked) Oop* __fastcall Interpreter::primitiveReturnInstVar(Oop* const sp, primargcount_t) +{ + _asm + { + // We need a to extract the inst var index from the byte codes, which should be in packed SmallInteger form + // 1 Nop + // 2 PushInstVarN + // 3(inst var index) + // 4 ReturnStackTop + + mov ecx, [m_registers.m_oopNewMethod] + cmp [m_bStepping], 0 + mov ecx, [ecx]OTE.m_location + mov edx, [esi] // ecx = receiver Oop at stack top + movzx ecx, [ecx]CompiledMethod.m_byteCodes+2 // Get bytecodes into eax - note that it MUST be a SmallInteger + mov edx, [edx]OTE.m_location // edx points at receiver object + jnz debugStep + mov eax, esi + mov edx, [edx]VariantObject.m_fields[ecx*OOPSIZE] + mov [esi], edx // Overwrite receiver with inst.var Oop + ret + + debugStep: + mov eax, 90000009H + ret + } +} + #else Oop* __fastcall Interpreter::primitiveReturnSelf(Oop* const sp, primargcount_t argCount) { @@ -132,6 +161,23 @@ Oop* __fastcall Interpreter::primitiveReturnStaticZero(Oop* const sp, primargcou return primitiveFailure(_PrimitiveFailureCode::DebugStep); } } + +Oop* __fastcall Interpreter::primitiveReturnInstVar(Oop* const sp, primargcount_t) +{ + SmallUinteger byteCodes = m_registers.m_oopNewMethod->m_location->m_byteCodes; + PointersOTE* oteReceiver = reinterpret_cast(*sp); + size_t index = (byteCodes >> 16) & 0xff; + if (!m_bStepping) + { + + *sp = oteReceiver->m_location->m_fields[index]; + return sp; +} + else + { + return primitiveFailure(_PrimitiveFailureCode::DebugStep); + } +} #endif // In order to keep the message lookup routines 'tight' we ensure that the infrequently executed code diff --git a/Core/DolphinVM/ist.h b/Core/DolphinVM/ist.h index bec63c91c9..1a903cfb27 100755 --- a/Core/DolphinVM/ist.h +++ b/Core/DolphinVM/ist.h @@ -176,7 +176,9 @@ HMODULE GetModuleContaining(LPCVOID pFunc); #endif #ifdef _M_X64 +#define OOPSIZE 8 #define PORT64(s) #error(s) #else +#define OOPSIZE 4 #define PORT64(s) #endif