|
| 1 | +/* Automatically generated by |
| 2 | + SmartSyntaxPluginCodeGenerator * VMMaker.oscog-eem.3636 uuid: 152db94e-b042-4e5b-a8aa-ac1b663ffe2a |
| 3 | + (Compiler-ct.519) |
| 4 | + from |
| 5 | + PseudoTTYPlugin VMConstruction-Plugins-PseudoTTYPlugin-dtl.5 uuid: 47f24fad-e652-4427-9f4e-6fad746c4c55 |
| 6 | + */ |
| 7 | +static char __buildInfo[] = "PseudoTTYPlugin VMConstruction-Plugins-PseudoTTYPlugin-dtl.5 uuid: 47f24fad-e652-4427-9f4e-6fad746c4c55 " __DATE__ ; |
| 8 | + |
| 9 | + |
| 10 | +#include "config.h" |
| 11 | +#include <math.h> |
| 12 | +#include "sqMathShim.h" |
| 13 | +#include <stdio.h> |
| 14 | +#include <stdlib.h> |
| 15 | +#include <string.h> |
| 16 | +#include <time.h> |
| 17 | + |
| 18 | +/* Do not include the entire sq.h file but just those parts needed. */ |
| 19 | +#include "sqConfig.h" /* Configuration options */ |
| 20 | +#include "sqVirtualMachine.h" /* The virtual machine proxy definition */ |
| 21 | +#include "sqPlatformSpecific.h" /* Platform specific definitions */ |
| 22 | + |
| 23 | +#include "PseudoTTYPlugin.h" |
| 24 | +#include "sqMemoryAccess.h" |
| 25 | + |
| 26 | +#define true 1 |
| 27 | +#define false 0 |
| 28 | +#define null 0 /* using 'null' because nil is predefined in Think C */ |
| 29 | +#ifdef SQUEAK_BUILTIN_PLUGIN |
| 30 | +# undef EXPORT |
| 31 | +# define EXPORT(returnType) static returnType |
| 32 | +# define INT_EXT "(i)" |
| 33 | +#else |
| 34 | +# define INT_EXT "(e)" |
| 35 | +#endif |
| 36 | + |
| 37 | + |
| 38 | +/*** Function Prototypes ***/ |
| 39 | +static AsyncFile * asyncFileValueOf(sqInt oop); |
| 40 | +EXPORT(const char*) getModuleName(void); |
| 41 | +EXPORT(sqInt) initialiseModule(void); |
| 42 | +EXPORT(sqInt) primPtyClose(void); |
| 43 | +EXPORT(sqInt) primPtyForkAndExec(void); |
| 44 | +EXPORT(sqInt) primPtyForkChildAndExec(void); |
| 45 | +EXPORT(sqInt) primPtyWindowSize(void); |
| 46 | +EXPORT(sqInt) setInterpreter(struct VirtualMachine *anInterpreter); |
| 47 | +EXPORT(sqInt) shutdownModule(void); |
| 48 | + |
| 49 | + |
| 50 | +/*** Variables ***/ |
| 51 | + |
| 52 | +#if !defined(SQUEAK_BUILTIN_PLUGIN) |
| 53 | +static sqInt (*classByteArray)(void); |
| 54 | +static sqInt (*failed)(void); |
| 55 | +static void * (*firstIndexableField)(sqInt oop); |
| 56 | +static sqInt (*instantiateClassindexableSize)(sqInt classPointer, sqInt size); |
| 57 | +#if !defined(integerObjectOf) |
| 58 | +static sqInt (*integerObjectOf)(sqInt value); |
| 59 | +#endif |
| 60 | +#if !defined(integerValueOf) |
| 61 | +static sqInt (*integerValueOf)(sqInt oop); |
| 62 | +#endif |
| 63 | +static void * (*ioLoadFunctionFrom)(char *functionName, char *moduleName); |
| 64 | +static sqInt (*isBytes)(sqInt oop); |
| 65 | +#if !defined(isIntegerObject) |
| 66 | +static sqInt (*isIntegerObject)(sqInt objectPointer); |
| 67 | +#endif |
| 68 | +static sqInt (*isPointers)(sqInt oop); |
| 69 | +static sqInt (*methodReturnValue)(sqInt oop); |
| 70 | +static sqInt (*pop)(sqInt nItems); |
| 71 | +static sqInt (*popRemappableOop)(void); |
| 72 | +static sqInt (*primitiveFailFor)(sqInt reasonCode); |
| 73 | +static sqInt (*pushRemappableOop)(sqInt oop); |
| 74 | +static sqInt (*slotSizeOf)(sqInt oop); |
| 75 | +static sqInt (*stObjectatput)(sqInt array, sqInt index, sqInt value); |
| 76 | +static sqInt (*stackValue)(sqInt offset); |
| 77 | +static sqInt (*success)(sqInt aBoolean); |
| 78 | +#else /* !defined(SQUEAK_BUILTIN_PLUGIN) */ |
| 79 | +extern sqInt classByteArray(void); |
| 80 | +extern sqInt failed(void); |
| 81 | +extern void * firstIndexableField(sqInt oop); |
| 82 | +extern sqInt instantiateClassindexableSize(sqInt classPointer, sqInt size); |
| 83 | +#if !defined(integerObjectOf) |
| 84 | +extern sqInt integerObjectOf(sqInt value); |
| 85 | +#endif |
| 86 | +#if !defined(integerValueOf) |
| 87 | +extern sqInt integerValueOf(sqInt oop); |
| 88 | +#endif |
| 89 | +extern void * ioLoadFunctionFrom(char *functionName, char *moduleName); |
| 90 | +extern sqInt isBytes(sqInt oop); |
| 91 | +#if !defined(isIntegerObject) |
| 92 | +extern sqInt isIntegerObject(sqInt objectPointer); |
| 93 | +#endif |
| 94 | +extern sqInt isPointers(sqInt oop); |
| 95 | +extern sqInt methodReturnValue(sqInt oop); |
| 96 | +extern sqInt pop(sqInt nItems); |
| 97 | +extern sqInt popRemappableOop(void); |
| 98 | +extern sqInt primitiveFailFor(sqInt reasonCode); |
| 99 | +extern sqInt pushRemappableOop(sqInt oop); |
| 100 | +extern sqInt slotSizeOf(sqInt oop); |
| 101 | +extern sqInt stObjectatput(sqInt array, sqInt index, sqInt value); |
| 102 | +extern sqInt stackValue(sqInt offset); |
| 103 | +extern sqInt success(sqInt aBoolean); |
| 104 | +extern |
| 105 | +#endif |
| 106 | +struct VirtualMachine* interpreterProxy; |
| 107 | +static const char *moduleName = "PseudoTTYPlugin VMConstruction-Plugins-PseudoTTYPlugin-dtl.5 " INT_EXT; |
| 108 | +static sqInt sCOAFfn; |
| 109 | + |
| 110 | + |
| 111 | +/*** Methods ***/ |
| 112 | + |
| 113 | + |
| 114 | +/* Return a pointer to the first byte of the async file record within the |
| 115 | + given Smalltalk bytes object, or nil if oop is not an async file record. |
| 116 | + */ |
| 117 | + |
| 118 | + /* PseudoTTYPlugin>>#asyncFileValueOf: */ |
| 119 | +static AsyncFile * |
| 120 | +asyncFileValueOf(sqInt oop) |
| 121 | +{ |
| 122 | + success((!(isIntegerObject(oop))) |
| 123 | + && ((isBytes(oop)) |
| 124 | + && ((slotSizeOf(oop)) == (sizeof(AsyncFile))))); |
| 125 | + if (failed()) { |
| 126 | + return null; |
| 127 | + } |
| 128 | + return ((AsyncFile *) (firstIndexableField(oop))); |
| 129 | +} |
| 130 | + |
| 131 | + |
| 132 | +/* Note: This is hardcoded so it can be run from Squeak. |
| 133 | + The module name is used for validating a module *after* |
| 134 | + it is loaded to check if it does really contain the module |
| 135 | + we're thinking it contains. This is important! */ |
| 136 | + |
| 137 | + /* InterpreterPlugin>>#getModuleName */ |
| 138 | +EXPORT(const char*) |
| 139 | +getModuleName(void) |
| 140 | +{ |
| 141 | + return moduleName; |
| 142 | +} |
| 143 | + |
| 144 | + |
| 145 | +/* We have to load AsyncFile first, to get the sessionID. */ |
| 146 | + |
| 147 | + /* PseudoTTYPlugin>>#initialiseModule */ |
| 148 | +EXPORT(sqInt) |
| 149 | +initialiseModule(void) |
| 150 | +{ |
| 151 | + ioLoadFunctionFrom("initializeModule", "AsynchFilePlugin"); |
| 152 | + return ptyInit(); |
| 153 | +} |
| 154 | + |
| 155 | + /* PseudoTTYPlugin>>#primitivePtyClose: */ |
| 156 | +EXPORT(sqInt) |
| 157 | +primPtyClose(void) |
| 158 | +{ |
| 159 | + AsyncFile *f; |
| 160 | + sqInt fHandle; |
| 161 | + |
| 162 | + fHandle = stackValue(0); |
| 163 | + f = asyncFileValueOf(fHandle); |
| 164 | + if (!(failed())) { |
| 165 | + ptyClose(f); |
| 166 | + } |
| 167 | + if (!(failed())) { |
| 168 | + pop(1); |
| 169 | + } |
| 170 | + return null; |
| 171 | +} |
| 172 | + |
| 173 | + /* PseudoTTYPlugin>>#primitivePtyForkAndExec:arguments:semaIndex: */ |
| 174 | +EXPORT(sqInt) |
| 175 | +primPtyForkAndExec(void) |
| 176 | +{ |
| 177 | + char *argIdx; |
| 178 | + sqInt argLen; |
| 179 | + sqInt args; |
| 180 | + sqInt cmd; |
| 181 | + char *cmdIdx; |
| 182 | + sqInt cmdLen; |
| 183 | + AsyncFile *f; |
| 184 | + sqInt fOop; |
| 185 | + sqInt semaIndex; |
| 186 | + |
| 187 | + if (!(isIntegerObject((semaIndex = stackValue(0))))) { |
| 188 | + return primitiveFailFor(PrimErrBadArgument); |
| 189 | + } |
| 190 | + cmd = stackValue(2); |
| 191 | + args = stackValue(1); |
| 192 | + semaIndex = integerValueOf(semaIndex); |
| 193 | + success(isBytes(cmd)); |
| 194 | + success(isPointers(args)); |
| 195 | + if (failed()) { |
| 196 | + return null; |
| 197 | + } |
| 198 | + cmdIdx = firstIndexableField(cmd); |
| 199 | + |
| 200 | + /* in bytes */ |
| 201 | + cmdLen = slotSizeOf(cmd); |
| 202 | + argIdx = firstIndexableField(args); |
| 203 | + |
| 204 | + /* in fields */ |
| 205 | + argLen = slotSizeOf(args); |
| 206 | + fOop = instantiateClassindexableSize(classByteArray(), sizeof(AsyncFile)); |
| 207 | + f = asyncFileValueOf(fOop); |
| 208 | + if (!(failed())) { |
| 209 | + ptyForkAndExec(f, semaIndex, cmdIdx, cmdLen, argIdx, argLen); |
| 210 | + } |
| 211 | + if (!(failed())) { |
| 212 | + methodReturnValue(fOop); |
| 213 | + } |
| 214 | + return null; |
| 215 | +} |
| 216 | + |
| 217 | + |
| 218 | +/* Answer a handle for an async file connected to the forked process on a |
| 219 | + pty, and store |
| 220 | + the pid of the forked child process in singleObjectContainer, which is an |
| 221 | + array of size |
| 222 | + one or any similar object. |
| 223 | + */ |
| 224 | + |
| 225 | + /* PseudoTTYPlugin>>#primitivePtyForkAndExec:arguments:semaIndex:childPidContainer: */ |
| 226 | +EXPORT(sqInt) |
| 227 | +primPtyForkChildAndExec(void) |
| 228 | +{ |
| 229 | + char *argIdx; |
| 230 | + sqInt argLen; |
| 231 | + sqInt args; |
| 232 | + pid_t childPid; |
| 233 | + sqInt cmd; |
| 234 | + char *cmdIdx; |
| 235 | + sqInt cmdLen; |
| 236 | + AsyncFile *f; |
| 237 | + sqInt fOop; |
| 238 | + sqInt pidContainer; |
| 239 | + sqInt semaIndex; |
| 240 | + sqInt singleObjectContainer; |
| 241 | + |
| 242 | + if (!(isIntegerObject((semaIndex = stackValue(1))))) { |
| 243 | + return primitiveFailFor(PrimErrBadArgument); |
| 244 | + } |
| 245 | + cmd = stackValue(3); |
| 246 | + args = stackValue(2); |
| 247 | + semaIndex = integerValueOf(semaIndex); |
| 248 | + singleObjectContainer = stackValue(0); |
| 249 | + success(isBytes(cmd)); |
| 250 | + success(isPointers(args)); |
| 251 | + success((isPointers(singleObjectContainer)) |
| 252 | + && ((slotSizeOf(singleObjectContainer)) > 0)); |
| 253 | + if (failed()) { |
| 254 | + return null; |
| 255 | + } |
| 256 | + cmdIdx = firstIndexableField(cmd); |
| 257 | + |
| 258 | + /* in bytes */ |
| 259 | + cmdLen = slotSizeOf(cmd); |
| 260 | + argIdx = firstIndexableField(args); |
| 261 | + |
| 262 | + /* in fields */ |
| 263 | + argLen = slotSizeOf(args); |
| 264 | + pushRemappableOop(singleObjectContainer); |
| 265 | + fOop = instantiateClassindexableSize(classByteArray(), sizeof(AsyncFile)); |
| 266 | + pidContainer = popRemappableOop(); |
| 267 | + f = asyncFileValueOf(fOop); |
| 268 | + if (failed()) { |
| 269 | + childPid = -1; |
| 270 | + } |
| 271 | + else { |
| 272 | + childPid = ptyForkAndExec(f, semaIndex, cmdIdx, cmdLen, argIdx, argLen); |
| 273 | + } |
| 274 | + stObjectatput(pidContainer, 1, integerObjectOf(childPid)); |
| 275 | + if (!(failed())) { |
| 276 | + methodReturnValue(fOop); |
| 277 | + } |
| 278 | + return null; |
| 279 | +} |
| 280 | + |
| 281 | + /* PseudoTTYPlugin>>#primitivePtyWindowSize:cols:rows: */ |
| 282 | +EXPORT(sqInt) |
| 283 | +primPtyWindowSize(void) |
| 284 | +{ |
| 285 | + sqInt cols; |
| 286 | + AsyncFile *f; |
| 287 | + sqInt fHandle; |
| 288 | + sqInt rows; |
| 289 | + |
| 290 | + if (!((isIntegerObject((cols = stackValue(1)))) |
| 291 | + && (isIntegerObject((rows = stackValue(0)))))) { |
| 292 | + return primitiveFailFor(PrimErrBadArgument); |
| 293 | + } |
| 294 | + fHandle = stackValue(2); |
| 295 | + cols = integerValueOf(cols); |
| 296 | + rows = integerValueOf(rows); |
| 297 | + f = asyncFileValueOf(fHandle); |
| 298 | + if (!(failed())) { |
| 299 | + ptyWindowSize(f, cols, rows); |
| 300 | + } |
| 301 | + if (!(failed())) { |
| 302 | + pop(3); |
| 303 | + } |
| 304 | + return null; |
| 305 | +} |
| 306 | + |
| 307 | + |
| 308 | +/* Note: This is coded so that it can be run in Squeak. */ |
| 309 | + |
| 310 | + /* InterpreterPlugin>>#setInterpreter: */ |
| 311 | +EXPORT(sqInt) |
| 312 | +setInterpreter(struct VirtualMachine *anInterpreter) |
| 313 | +{ |
| 314 | + sqInt ok; |
| 315 | + |
| 316 | + interpreterProxy = anInterpreter; |
| 317 | + |
| 318 | + /* This may seem tautological, but in a real plugin it checks that the VM provides |
| 319 | + the version the plugin was compiled against which is the version the plugin expects. */ |
| 320 | + ok = ((interpreterProxy->majorVersion()) == (VM_PROXY_MAJOR)) |
| 321 | + && ((interpreterProxy->minorVersion()) >= (VM_PROXY_MINOR)); |
| 322 | + if (ok) { |
| 323 | + |
| 324 | +#if !defined(SQUEAK_BUILTIN_PLUGIN) |
| 325 | + classByteArray = interpreterProxy->classByteArray; |
| 326 | + failed = interpreterProxy->failed; |
| 327 | + firstIndexableField = interpreterProxy->firstIndexableField; |
| 328 | + instantiateClassindexableSize = interpreterProxy->instantiateClassindexableSize; |
| 329 | +#if !defined(integerObjectOf) |
| 330 | + integerObjectOf = interpreterProxy->integerObjectOf; |
| 331 | +#endif |
| 332 | +#if !defined(integerValueOf) |
| 333 | + integerValueOf = interpreterProxy->integerValueOf; |
| 334 | +#endif |
| 335 | + ioLoadFunctionFrom = interpreterProxy->ioLoadFunctionFrom; |
| 336 | + isBytes = interpreterProxy->isBytes; |
| 337 | +#if !defined(isIntegerObject) |
| 338 | + isIntegerObject = interpreterProxy->isIntegerObject; |
| 339 | +#endif |
| 340 | + isPointers = interpreterProxy->isPointers; |
| 341 | + methodReturnValue = interpreterProxy->methodReturnValue; |
| 342 | + pop = interpreterProxy->pop; |
| 343 | + popRemappableOop = interpreterProxy->popRemappableOop; |
| 344 | + primitiveFailFor = interpreterProxy->primitiveFailFor; |
| 345 | + pushRemappableOop = interpreterProxy->pushRemappableOop; |
| 346 | + slotSizeOf = interpreterProxy->slotSizeOf; |
| 347 | + stObjectatput = interpreterProxy->stObjectatput; |
| 348 | + stackValue = interpreterProxy->stackValue; |
| 349 | + success = interpreterProxy->success; |
| 350 | +#endif /* !defined(SQUEAK_BUILTIN_PLUGIN) */ |
| 351 | + } |
| 352 | + return ok; |
| 353 | +} |
| 354 | + |
| 355 | + /* PseudoTTYPlugin>>#shutdownModule */ |
| 356 | +EXPORT(sqInt) |
| 357 | +shutdownModule(void) |
| 358 | +{ |
| 359 | + return ptyShutdown(); |
| 360 | +} |
| 361 | + |
| 362 | +/*** Exports ***/ |
| 363 | + |
| 364 | +#ifdef SQUEAK_BUILTIN_PLUGIN |
| 365 | + |
| 366 | +static char _m[] = "PseudoTTYPlugin"; |
| 367 | +void* PseudoTTYPlugin_exports[][3] = { |
| 368 | + {(void*)_m, "getModuleName", (void*)getModuleName}, |
| 369 | + {(void*)_m, "initialiseModule", (void*)initialiseModule}, |
| 370 | + {(void*)_m, "primPtyClose\000\001\000", (void*)primPtyClose}, |
| 371 | + {(void*)_m, "primPtyForkAndExec\000\001\000", (void*)primPtyForkAndExec}, |
| 372 | + {(void*)_m, "primPtyForkChildAndExec\000\001\000", (void*)primPtyForkChildAndExec}, |
| 373 | + {(void*)_m, "primPtyWindowSize\000\001\000", (void*)primPtyWindowSize}, |
| 374 | + {(void*)_m, "setInterpreter", (void*)setInterpreter}, |
| 375 | + {(void*)_m, "shutdownModule", (void*)shutdownModule}, |
| 376 | + {NULL, NULL, NULL} |
| 377 | +}; |
| 378 | + |
| 379 | +#else // ifdef SQ_BUILTIN_PLUGIN |
| 380 | + |
| 381 | +#if SPURVM |
| 382 | +EXPORT(signed short) primPtyCloseMetadata = 0x100; |
| 383 | +EXPORT(signed short) primPtyForkAndExecMetadata = 0x100; |
| 384 | +EXPORT(signed short) primPtyForkChildAndExecMetadata = 0x100; |
| 385 | +EXPORT(signed short) primPtyWindowSizeMetadata = 0x100; |
| 386 | +#endif // SPURVM |
| 387 | + |
| 388 | +#endif // ifdef SQ_BUILTIN_PLUGIN |
0 commit comments