Skip to content

Commit

Permalink
#590 : support output type list
Browse files Browse the repository at this point in the history
  • Loading branch information
arakov committed May 17, 2024
1 parent c1f94af commit b17017c
Show file tree
Hide file tree
Showing 23 changed files with 352 additions and 60 deletions.
1 change: 1 addition & 0 deletions dat/sg/syntax60.txt
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ L0_F ::=
L2_F ::=
L2_OP L2_F
| DOT MESSAGE { L3_F | eps ^PROPERTY_OPERATION }
| ":" ^EXPRESSION identifier TEMPLATE_ARG ^ TEMPLATE_EXPR_BLOCK
| L4_OP+ L5_OP* L6_OP? L7_OP* L8_OP? L9_OP?
| L5_OP+ L6_OP? L7_OP* L8_OP? L9_OP?
| L6_OP L7_OP* L8_OP? L9_OP?
Expand Down
9 changes: 9 additions & 0 deletions doc/api/system-dynamic.html
Original file line number Diff line number Diff line change
Expand Up @@ -2350,6 +2350,15 @@ <H3>Extension Summary</H3>
<CODE>
</CODE></TD>
<TD CLASS="colLast">
<CODE>__createProxyType()
</CODE>
</TD>
</TR>
<TR CLASS="altColor">
<TD CLASS="colFirst">
<CODE>
</CODE></TD>
<TD CLASS="colLast">
<CODE>mixInto(<SPAN CLASS="memberNameLink"><A HREF="system.html#Object">Object</A></SPAN> role)
</CODE>
</TD>
Expand Down
12 changes: 11 additions & 1 deletion doc/todo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,18 @@ In development:
- chat sample
- #590 : creating a dynamic interface wrapper (the "class" is created in perm heap, clone the interface and fill with redirect statements)
* #590 : functional test
* #590 : vm : CreateProxyType
* #590 : sample : create a dynamic interface wrapper
* rename CreateProxyTypeLA to InjectProxyLA, the input parameter must contain the target object, the function must verify that
the target proxy is marked as proxy dispatcher (); the target type is marked
as weak interface (the output is not specified); the function will create proxy vmt and inject it to the proxy : otherwise it returns 0

* the api entry must override
* perm alloc must be struct
* #590 : only stateless type can be used
* #590 : proxy dispatcher : contains only a single field and a custom dispatcher
--------------------------------------
* #590 : elenavm : dynamic class inheritance - allocate in perm, copy vmt with custom routine
* #590 : output type list - ignore anonymous / proxy classes

=== Iteration 24 ===
--------------------------------------
Expand Down
9 changes: 8 additions & 1 deletion elenasrc3/common/streams.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// This header contains the declaration of abstract stream reader
// and writer classes
// (C)2021-2023, by Aleksey Rakov
// (C)2021-2024, by Aleksey Rakov
//---------------------------------------------------------------------------

#ifndef STREAMS_H
Expand Down Expand Up @@ -37,6 +37,13 @@ namespace elena_lang

return value;
}
static unsigned long long getQWord(MemoryBase* source, pos_t position)
{
unsigned long long value = 0;
source->read(position, &value, sizeof(value));

return value;
}

static void maskDWord(MemoryBase* source, pos_t position, ref_t mask)
{
Expand Down
2 changes: 1 addition & 1 deletion elenasrc3/elc/cliconst.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace elena_lang
{
#define ELC_REVISION_NUMBER 0x0005
#define ELC_REVISION_NUMBER 0x0006

#if defined _M_IX86 || _M_X64

Expand Down
2 changes: 1 addition & 1 deletion elenasrc3/elenart/rtcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace elena_lang
{

#define ELENART_REVISION_NUMBER 0x0001
#define ELENART_REVISION_NUMBER 0x0002

}

Expand Down
9 changes: 9 additions & 0 deletions elenasrc3/elenart/windows/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,15 @@ EXTERN_DLL_EXPORT void WaitForSignalsGCLA(size_t count, void* handles)
SystemRoutineProvider::GCWaitForSignals(count, handles);
}

/// <summary>
/// Creates a dynamic proxy class inheriting the given VMT
/// </summary>
/// <returns>a reference to dynamically created VMT</returns>
EXTERN_DLL_EXPORT void* CreateProxyTypeLA(void* classPtr, int staticLength, int nameIndex, void* handler)
{
return (void*)machine->inherit(systemEnv, classPtr, staticLength, nameIndex, (addr_t*)&handler, 1);
}

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
Expand Down
10 changes: 6 additions & 4 deletions elenasrc3/engine/bcwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3642,15 +3642,17 @@ void ByteCodeWriter :: saveProcedure(BuildNode node, Scope& scope, bool classMod
endDebugInfo(scope);
}

void ByteCodeWriter :: saveVMT(BuildNode node, Scope& scope, pos_t sourcePathRef,
void ByteCodeWriter :: saveVMT(ClassInfo& info, BuildNode node, Scope& scope, pos_t sourcePathRef,
ReferenceMap& paths, bool tapeOptMode, bool threadFriendly)
{
BuildNode current = node.firstChild();
while (current != BuildKey::None) {
if (current == BuildKey::Method) {
pos_t methodSourcePathRef = sourcePathRef;

MethodEntry entry = { current.arg.reference, scope.code->position() };
auto methodInfo = info.methods.get(current.arg.reference);

MethodEntry entry = { current.arg.reference, scope.code->position(), methodInfo.outputRef };
scope.vmt->write(&entry, sizeof(MethodEntry));

BuildNode pathNode = current.findChild(BuildKey::Path);
Expand Down Expand Up @@ -3726,10 +3728,10 @@ void ByteCodeWriter :: saveClass(BuildNode node, SectionScopeBase* moduleScope,

openClassDebugInfo(scope, moduleScope->module->resolveReference(node.arg.reference & ~mskAnyRef), info.header.flags);
saveFieldDebugInfo(scope, info);
saveVMT(node, scope, sourcePath, paths, tapeOptMode, threadFriendly);
saveVMT(info, node, scope, sourcePath, paths, tapeOptMode, threadFriendly);
endDebugInfo(scope);
}
else saveVMT(node, scope, INVALID_POS, paths, tapeOptMode, threadFriendly);
else saveVMT(info, node, scope, INVALID_POS, paths, tapeOptMode, threadFriendly);

pos_t size = vmtWriter.position() - classPosition;
vmtSection->write(classPosition - 4, &size, sizeof(size));
Expand Down
2 changes: 1 addition & 1 deletion elenasrc3/engine/bcwriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ namespace elena_lang
void saveProcedure(BuildNode node, Scope& scope, bool classMode, pos_t sourcePathRef,
ReferenceMap& paths, bool tapeOptMode, bool threadFriendly);

void saveVMT(BuildNode node, Scope& scope, pos_t sourcePathRef, ReferenceMap& paths,
void saveVMT(ClassInfo& info, BuildNode node, Scope& scope, pos_t sourcePathRef, ReferenceMap& paths,
bool tapeOptMode, bool threadFriendly);

void saveSymbol(BuildNode node, SectionScopeBase* moduleScope, int minimalArgList,
Expand Down
20 changes: 17 additions & 3 deletions elenasrc3/engine/elena.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,21 @@ namespace elena_lang
virtual void writeLabelAddress(pos_t label, MemoryWriter& writer, ref_t mask) = 0;
};

typedef CachedList<Pair<mssg_t, ref_t>, 10> CachedOutputTypeList;

// --- JITCompilerBase ---
class JITCompilerBase
{
public:
struct VMTFixInfo
{
addr_t parentAddress;
addr_t classClassAddress;
addr_t outputListAddress;
ref_t flags;
pos_t count;
};

virtual void prepare(
LibraryLoaderBase* loader,
ImageProviderBase* imageProvider,
Expand All @@ -539,16 +550,18 @@ namespace elena_lang

virtual void compileMetaList(ReferenceHelperBase* helper, MemoryReader& reader, MemoryWriter& writer, pos_t length) = 0;

virtual void compileOutputTypeList(ReferenceHelperBase* helper, MemoryWriter& writer, CachedOutputTypeList& outputTypeList) = 0;

virtual pos_t getStaticCounter(MemoryBase* statSection, bool emptyNotAllowed = false) = 0;

virtual pos_t getVMTLength(void* targetVMT) = 0;
virtual addr_t findMethodAddress(void* entries, mssg_t message) = 0;
virtual pos_t findMethodOffset(void* entries, mssg_t message) = 0;

virtual void allocateVMT(MemoryWriter& vmtWriter, pos_t flags, pos_t vmtLength, pos_t staticLength) = 0;
virtual void allocateVMT(MemoryWriter& vmtWriter, pos_t flags, pos_t vmtLength,
pos_t staticLength, bool withOutputList) = 0;
virtual void addVMTEntry(mssg_t message, addr_t codeAddress, void* targetVMT, pos_t& entryCount) = 0;
virtual void updateVMTHeader(MemoryWriter& vmtWriter, addr_t parentAddress, addr_t classClassAddress,
ref_t flags, pos_t count, FieldAddressMap& staticValues, bool virtualMode) = 0;
virtual void updateVMTHeader(MemoryWriter& vmtWriter, VMTFixInfo& fixInfo, FieldAddressMap& staticValues, bool virtualMode) = 0;
virtual pos_t copyParentVMT(void* parentVMT, void* targetVMT) = 0;

virtual void allocateHeader(MemoryWriter& writer, addr_t vmtAddress, int length,
Expand Down Expand Up @@ -1107,6 +1120,7 @@ namespace elena_lang
{
mssg_t message;
pos_t codeOffset;
ref_t outputRef;
};

// --- DebugLineInfo ---
Expand Down
3 changes: 2 additions & 1 deletion elenasrc3/engine/elenaconst.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace elena_lang
// --- ELENA Module structure constants ---
constexpr auto ELENA_SIGNITURE = "ELENA."; // the stand alone image
constexpr auto ELENA_VM_SIGNITURE = "VM.ELENA."; // the stand alone image
constexpr auto MODULE_SIGNATURE = "ELENA.0610"; // the module version
constexpr auto MODULE_SIGNATURE = "ELENA.0611"; // the module version
constexpr auto DEBUG_MODULE_SIGNATURE = "ED.06";

// --- ELENA core module names ---
Expand Down Expand Up @@ -209,6 +209,7 @@ namespace elena_lang
constexpr ref_t elGroup = 0x10000000;
constexpr ref_t elPacked = 0x20000000;
constexpr ref_t elTemplatebased = 0x40000000;
constexpr ref_t elWithOutputList = 0x80000000; // NOTE : this flag is set automatically by JIT linker

constexpr ref_t elDebugMask = 0x001F0000;
constexpr ref_t elDebugDWORD = 0x00010000;
Expand Down
6 changes: 3 additions & 3 deletions elenasrc3/engine/elenamachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ constexpr int elObjectOffset = elObjectOffset64;

inline uintptr_t RetrieveStaticField(uintptr_t ptr, int index)
{
uintptr_t str = *(uintptr_t*)(ptr - sizeof(VMTHeader) - index * sizeof(uintptr_t));
uintptr_t str = *(uintptr_t*)(ptr - sizeof(VMTHeader) + index * sizeof(uintptr_t));

return str;
}
Expand Down Expand Up @@ -74,7 +74,7 @@ addr_t ELENAMachine :: inherit(SystemEnv* env, void* srcVMTPtr, int staticLen, i
uintptr_t namePtr = RetrieveStaticField((uintptr_t)srcVMTPtr, nameIndex);
uintptr_t stringVMT = RetrieveVMT(namePtr);

IdentifierString dynamicName("$proxy");
IdentifierString dynamicName("proxy$");
if (namePtr) {
dynamicName.append((const char*)namePtr);
}
Expand All @@ -92,7 +92,7 @@ addr_t ELENAMachine :: inherit(SystemEnv* env, void* srcVMTPtr, int staticLen, i

// HOTFIX : copy build-in static variables
uintptr_t* staticFields = (uintptr_t*)(ptr + staticLen * sizeof(uintptr_t));
for (int i = 0; i < staticLen; i++) {
for (int i = 1; i <= staticLen; i++) {
staticFields[-i] = RetrieveStaticField((uintptr_t)srcVMTPtr, -i);
}
staticFields[nameIndex] = nameAddr;
Expand Down
Loading

0 comments on commit b17017c

Please sign in to comment.