Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 7d25ddc

Browse files
committed
[[ ExternalsApiV5 ]] Refactored type mapping to use simple objects.
[[ ExternalsApiV5 ]] Reworked variant generation to handle direct java bindings. [[ ExternalsApiV5 ]] Added support for using c, objc or java for handler mappings.
1 parent f509a64 commit 7d25ddc

File tree

11 files changed

+1205
-174
lines changed

11 files changed

+1205
-174
lines changed

lcidlc/lcidlc.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
4D12FFC817A3EF0F0004F700 /* Coder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D12FFC717A3EF0F0004F700 /* Coder.cpp */; };
1011
4D332C41178D7959005DFE92 /* EncodedJavaSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D332C3F178D7959005DFE92 /* EncodedJavaSupport.c */; };
1112
4D332C42178D7959005DFE92 /* EncodedSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D332C40178D7959005DFE92 /* EncodedSupport.c */; };
1213
4D4051A3176B2D340097F2D6 /* NativeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D4051A1176B2D340097F2D6 /* NativeType.cpp */; };
@@ -42,6 +43,8 @@
4243
/* End PBXContainerItemProxy section */
4344

4445
/* Begin PBXFileReference section */
46+
4D12FFC617A3EF0F0004F700 /* Coder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Coder.h; path = src/Coder.h; sourceTree = "<group>"; };
47+
4D12FFC717A3EF0F0004F700 /* Coder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Coder.cpp; path = src/Coder.cpp; sourceTree = "<group>"; };
4548
4D332C3F178D7959005DFE92 /* EncodedJavaSupport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = EncodedJavaSupport.c; path = src/EncodedJavaSupport.c; sourceTree = "<group>"; };
4649
4D332C40178D7959005DFE92 /* EncodedSupport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = EncodedSupport.c; path = src/EncodedSupport.c; sourceTree = "<group>"; };
4750
4D3B10121367E35D00E00C1E /* Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = ../rules/Release.xcconfig; sourceTree = SOURCE_ROOT; };
@@ -146,6 +149,8 @@
146149
4D9036A01398FC0800CBC7F6 /* Value.cpp */,
147150
4D9036A11398FC0800CBC7F6 /* Value.h */,
148151
4DED6D131760ECD5001DEF0C /* Support.java */,
152+
4D12FFC617A3EF0F0004F700 /* Coder.h */,
153+
4D12FFC717A3EF0F0004F700 /* Coder.cpp */,
149154
);
150155
name = Sources;
151156
sourceTree = "<group>";
@@ -301,6 +306,7 @@
301306
4D4051A3176B2D340097F2D6 /* NativeType.cpp in Sources */,
302307
4D332C41178D7959005DFE92 /* EncodedJavaSupport.c in Sources */,
303308
4D332C42178D7959005DFE92 /* EncodedSupport.c in Sources */,
309+
4D12FFC817A3EF0F0004F700 /* Coder.cpp in Sources */,
304310
);
305311
runOnlyForDeploymentPostprocessing = 0;
306312
};

lcidlc/src/Coder.cpp

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/*
2+
* Coder.cpp
3+
* lcidlc
4+
*
5+
* Created by Mark Waddingham on 27/07/2013.
6+
* Copyright 2013 Runtime Revolution. All rights reserved.
7+
*
8+
*/
9+
10+
#include <stdio.h>
11+
12+
#include "Core.h"
13+
#include "Coder.h"
14+
15+
struct Coder
16+
{
17+
FILE *stream;
18+
uint32_t depth;
19+
bool padded;
20+
};
21+
22+
static void CoderIndent(CoderRef self)
23+
{
24+
const char *s_tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
25+
fprintf(self -> stream, "%.*s", self -> depth > 32 ? 32 : self -> depth, s_tabs);
26+
}
27+
28+
bool CoderStart(const char *p_filename, CoderRef& r_coder)
29+
{
30+
bool t_success;
31+
t_success = true;
32+
33+
CoderRef self;
34+
self = nil;
35+
if (t_success)
36+
t_success = MCMemoryNew(self);
37+
38+
if (t_success)
39+
{
40+
self -> stream = fopen(p_filename, "w");
41+
if (self -> stream == nil)
42+
t_success = false;
43+
}
44+
45+
if (t_success)
46+
{
47+
self -> depth = 0;
48+
r_coder = self;
49+
}
50+
else
51+
MCMemoryDelete(self);
52+
53+
return t_success;
54+
}
55+
56+
bool CoderFinish(CoderRef self)
57+
{
58+
fclose(self -> stream);
59+
MCMemoryDelete(self);
60+
return true;
61+
}
62+
63+
void CoderCancel(CoderRef self)
64+
{
65+
CoderFinish(self);
66+
}
67+
68+
void CoderWriteLine(CoderRef self, const char *p_format, ...)
69+
{
70+
va_list t_args;
71+
va_start(t_args, p_format);
72+
vfprintf(self -> stream, p_format, t_args);
73+
va_end(t_args);
74+
fprintf(self -> stream, "\n");
75+
76+
self -> padded = false;
77+
}
78+
79+
void CoderWrite(CoderRef self, const char *p_format, ...)
80+
{
81+
va_list t_args;
82+
va_start(t_args, p_format);
83+
vfprintf(self -> stream, p_format, t_args);
84+
va_end(t_args);
85+
}
86+
87+
void CoderWriteStatement(CoderRef self, const char *p_format, ...)
88+
{
89+
CoderBeginStatement(self);
90+
91+
va_list t_args;
92+
va_start(t_args, p_format);
93+
vfprintf(self -> stream, p_format, t_args);
94+
va_end(t_args);
95+
96+
CoderEndStatement(self);
97+
}
98+
99+
void CoderBeginStatement(CoderRef self)
100+
{
101+
CoderIndent(self);
102+
}
103+
104+
void CoderEndStatement(CoderRef self)
105+
{
106+
fprintf(self -> stream, ";\n");
107+
108+
self -> padded = false;
109+
}
110+
111+
void CoderBeginPreprocessor(CoderRef self, const char *p_format, ...)
112+
{
113+
va_list t_args;
114+
va_start(t_args, p_format);
115+
vfprintf(self -> stream, p_format, t_args);
116+
va_end(t_args);
117+
fprintf(self -> stream, "\n");
118+
119+
self -> padded = false;
120+
}
121+
122+
void CoderEndPreprocessor(CoderRef self, const char *p_format, ...)
123+
{
124+
va_list t_args;
125+
va_start(t_args, p_format);
126+
vfprintf(self -> stream, p_format, t_args);
127+
va_end(t_args);
128+
fprintf(self -> stream, "\n");
129+
130+
self -> padded = false;
131+
}
132+
133+
void CoderBegin(CoderRef self, const char *p_format, ...)
134+
{
135+
if (*p_format != '\0')
136+
{
137+
CoderIndent(self);
138+
va_list t_args;
139+
va_start(t_args, p_format);
140+
vfprintf(self -> stream, p_format, t_args);
141+
va_end(t_args);
142+
fprintf(self -> stream, "\n");
143+
}
144+
CoderIndent(self);
145+
fprintf(self -> stream, "{\n");
146+
147+
self -> depth += 1;
148+
self -> padded = false;
149+
}
150+
151+
void CoderEndBegin(CoderRef self, const char *p_format, ...)
152+
{
153+
CoderEnd(self, "");
154+
CoderIndent(self);
155+
va_list t_args;
156+
va_start(t_args, p_format);
157+
vfprintf(self -> stream, p_format, t_args);
158+
va_end(t_args);
159+
fprintf(self -> stream, "\n");
160+
CoderBegin(self, "");
161+
162+
self -> padded = false;
163+
}
164+
165+
void CoderEnd(CoderRef self, const char *p_format, ...)
166+
{
167+
self -> depth -= 1;
168+
CoderIndent(self);
169+
fprintf(self -> stream, "}\n");
170+
if (*p_format != '\0')
171+
{
172+
CoderIndent(self);
173+
va_list t_args;
174+
va_start(t_args, p_format);
175+
vfprintf(self -> stream, p_format, t_args);
176+
va_end(t_args);
177+
fprintf(self -> stream, "\n");
178+
}
179+
180+
self -> padded = false;
181+
}
182+
183+
void CoderBeginIf(CoderRef self, const char *p_format, ...)
184+
{
185+
CoderIndent(self);
186+
fprintf(self -> stream, "if (");
187+
va_list t_args;
188+
va_start(t_args, p_format);
189+
vfprintf(self -> stream, p_format, t_args);
190+
va_end(t_args);
191+
fprintf(self -> stream, ")\n");
192+
CoderBegin(self, "");
193+
194+
self -> padded = false;
195+
}
196+
197+
void CoderElse(CoderRef self)
198+
{
199+
CoderEndBegin(self, "else");
200+
}
201+
202+
void CoderEndIf(CoderRef self)
203+
{
204+
CoderEnd(self, "");
205+
}
206+
207+
void CoderPad(CoderRef self)
208+
{
209+
if (self -> padded)
210+
return;
211+
212+
CoderWriteLine(self, "");
213+
self -> padded = true;
214+
}

lcidlc/src/Coder.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef __CODER__
2+
#define __CODER__
3+
4+
typedef struct Coder *CoderRef;
5+
6+
bool CoderStart(const char *p_filename, CoderRef& r_coder);
7+
bool CoderFinish(CoderRef self);
8+
9+
void CoderCancel(CoderRef self);
10+
11+
void CoderWriteLine(CoderRef self, const char *p_format, ...);
12+
void CoderWrite(CoderRef self, const char *p_format, ...);
13+
14+
void CoderWriteStatement(CoderRef self, const char *p_format, ...);
15+
16+
void CoderBeginStatement(CoderRef self);
17+
void CoderEndStatement(CoderRef self);
18+
19+
void CoderBeginPreprocessor(CoderRef self, const char *p_format, ...);
20+
void CoderEndPreprocessor(CoderRef self, const char *p_format, ...);
21+
22+
void CoderBegin(CoderRef self, const char *p_format, ...);
23+
void CoderEndBegin(CoderRef self, const char *p_format, ...);
24+
void CoderEnd(CoderRef self, const char *p_format, ...);
25+
26+
void CoderBeginIf(CoderRef self, const char *p_format, ...);
27+
void CoderElse(CoderRef self);
28+
void CoderEndIf(CoderRef self);
29+
30+
void CoderPad(CoderRef self);
31+
32+
#endif

lcidlc/src/Interface.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum InterfaceError
5656
kInterfaceErrorUnknownPlatform,
5757
kInterfaceErrorObjCNotSupported,
5858
kInterfaceErrorJavaNotSupported,
59+
kInterfaceErrorJavaImpliesNonIndirectReturn,
5960
};
6061

6162
////////////////////////////////////////////////////////////////////////////////
@@ -144,6 +145,8 @@ static bool InterfaceReport(InterfaceRef self, Position p_where, InterfaceError
144145
case kInterfaceErrorUnknownType:
145146
fprintf(stderr, "Unknown type '%s'\n", StringGetCStringPtr(NameGetString((NameRef)p_hint)));
146147
break;
148+
case kInterfaceErrorJavaImpliesInParam:
149+
fprintf(stderr, "Java mapped methods can only have 'in' parameters\n");
147150
case kInterfaceErrorUnknownHandlerMapping:
148151
fprintf(stderr, "Unknown handler mapping type '%s'\n", StringGetCStringPtr(NameGetString((NameRef)p_hint)));
149152
break;
@@ -156,6 +159,9 @@ static bool InterfaceReport(InterfaceRef self, Position p_where, InterfaceError
156159
case kInterfaceErrorJavaNotSupported:
157160
fprintf(stderr, "Java mapping not supported on platform '%s'\n", StringGetCStringPtr(NameGetString((NameRef)p_hint)));
158161
break;
162+
case kInterfaceErrorJavaImpliesNonIndirectReturn:
163+
fprintf(stderr, "Java mapped methods cannot have indirect return value\n");
164+
break;
159165
}
160166

161167
self -> invalid = true;
@@ -235,6 +241,10 @@ bool InterfaceBegin(InterfaceRef self, Position p_where, NameRef p_name)
235241
self -> where = p_where;
236242
self -> qualified_name = ValueRetain(p_name);
237243

244+
// MW-2013-07-29: [[ ExternalsApiV5 ]] Default mappings are to use C on all platforms.
245+
for(Platform i = kPlatformMac; i < __kPlatformCount__; i++)
246+
self -> use_mappings[i] = kHandlerMappingC;
247+
238248
return true;
239249
}
240250

@@ -403,13 +413,13 @@ bool InterfaceBeginHandler(InterfaceRef self, Position p_where, HandlerType p_ty
403413
// RULE: Variants of handlers must all have the same type.
404414
if (t_handler != nil &&
405415
t_handler -> type != p_type &&
406-
t_handler -> is_java == ((p_attr & kHandlerAttributeIsJava) != 0) &&
416+
/*t_handler -> is_java == ((p_attr & kHandlerAttributeIsJava) != 0) &&*/
407417
t_handler -> is_tail == ((p_attr & kHandlerAttributeIsTail) != 0))
408418
InterfaceReport(self, p_where, kInterfaceErrorCannotMixHandlerTypes, p_name);
409419

410420
// RULE: Methods must specify 'java'.
411-
if (p_type == kHandlerTypeMethod && (p_attr & kHandlerAttributeIsJava) == 0)
412-
InterfaceReport(self, p_where, kInterfaceErrorMethodsMustBeJava, p_name);
421+
/*if (p_type == kHandlerTypeMethod && (p_attr & kHandlerAttributeIsJava) == 0)
422+
InterfaceReport(self, p_where, kInterfaceErrorMethodsMustBeJava, p_name);*/
413423

414424
// RULE: Methods must not specify 'tail' since that is their purpose.
415425
if (p_type == kHandlerTypeMethod && (p_attr & kHandlerAttributeIsTail) != 0)
@@ -425,7 +435,7 @@ bool InterfaceBeginHandler(InterfaceRef self, Position p_where, HandlerType p_ty
425435

426436
// MW-2013-06-14: [[ ExternalsApiV5 ]] Set the attributes appropriate in the
427437
// handler.
428-
t_handler -> is_java = (p_attr & kHandlerAttributeIsJava) != 0;
438+
/*t_handler -> is_java = (p_attr & kHandlerAttributeIsJava) != 0;*/
429439
t_handler -> is_tail = (p_attr & kHandlerAttributeIsTail) != 0;
430440

431441
t_handler -> name = ValueRetain(p_name);
@@ -574,8 +584,11 @@ bool InterfaceDefineHandlerParameter(InterfaceRef self, Position p_where, Parame
574584
// MW-2013-06-14: [[ ExternalsApiV5 ]] New rule to check java methods have compatible
575585
// signature.
576586
// RULE: If java handler, then only in parameters are allowed.
577-
if (self -> current_handler -> is_java)
587+
/*if (self -> current_handler -> is_java)
578588
if (p_param_type != kParameterTypeIn)
589+
InterfaceReport(self, p_where, kInterfaceErrorJavaImpliesInParam, nil);*/
590+
if (t_variant -> mappings[kPlatformAndroid] == kHandlerMappingJava &&
591+
p_param_type != kParameterTypeIn)
579592
InterfaceReport(self, p_where, kInterfaceErrorJavaImpliesInParam, nil);
580593

581594
if (!MCMemoryResizeArray(t_variant -> parameter_count + 1, t_variant -> parameters, t_variant -> parameter_count))
@@ -603,6 +616,13 @@ bool InterfaceDefineHandlerReturn(InterfaceRef self, Position p_where, NameRef p
603616
HandlerVariant *t_variant;
604617
t_variant = &self -> current_handler -> variants[self -> current_handler -> variant_count - 1];
605618

619+
// MW-2013-07-27: [[ ExternalsApiV5 ]] New rule to check we don't use indirect on
620+
// java mapped methods.
621+
// RULE: If java handler, then only non-indirect return values are allowed.
622+
if (t_variant -> mappings[kPlatformAndroid] == kHandlerMappingJava &&
623+
p_indirect)
624+
InterfaceReport(self, p_where, kInterfaceErrorJavaImpliesNonIndirectReturn, nil);
625+
606626
InterfaceCheckType(self, p_where, p_type);
607627

608628
t_variant -> return_type = ValueRetain(p_type);

0 commit comments

Comments
 (0)