FskErr FskSSLWrite(void *a, const void *buf, int *bufLen) { FskSSL *fssl = a; FskErr err = kFskErrNone; int len = *bufLen; if (fssl->skt == NULL) return kFskErrOperationFailed; if (buf == NULL || len == 0) return kFskErrNone; xsBeginHost(fssl->vm->the); xsTry { xsVars(1); xsCall1_noResult(fssl->socket, xsID("attachData"), xsHostData(fssl->skt)); xsVar(0) = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(len)); FskMemCopy(xsGetHostData(xsVar(0)), buf, len); xsResult = xsCall2(fssl->ssl, xsID("write"), fssl->socket, xsVar(0)); *bufLen = xsToInteger(xsResult); if (*bufLen == 0) err = kFskErrNoData; xsCall0_noResult(xsVar(0), xsID("free")); } xsCatch { if (xsHas(xsException, xsID("code"))) err = xsToInteger(xsGet(xsException, xsID("code"))); if (err == kFskErrNone) err = kFskErrOperationFailed; } xsEndHost(fssl->vm->the); return err; }
void KprDebugMachineLoadView(KprDebugMachine self, int theView, char* thePath, int theLine) { FskErr err = kFskErrNone; KprDebug debug = self->debug; xsMachine* the = debug->the; // FskFileInfo info; // FskFileMapping map = NULL; // FskDebugStr("%s: %d - %s:%d", __FUNCTION__, theView, thePath, theLine); if (xsTypeOf(debug->behavior) == xsUndefinedType) goto bail; xsVar(0) = xsAccess(debug->behavior); if (xsFindResult(xsVar(0), xsID("onMachineFileChanged"))) { (void)xsCallFunction5(xsResult, xsVar(0), xsString(self->address), xsInteger(theView), xsNull, thePath ? xsString(thePath) : xsNull, xsInteger(theLine)); } // if (kFskErrNone == FskFileGetFileInfo(thePath, &info) && (kFskDirectoryItemIsFile == info.filetype)) { // unsigned char *data; // FskInt64 size; // BAIL_IF_ERR(err = FskFileMap(thePath, &data, &size, 0, &map)); // xsVar(0) = xsAccess(debug->behavior); // // if (xsFindResult(xsVar(0), xsID("onMachineFileChanged"))) { // (void)xsCallFunction5(xsResult, xsVar(0), xsString(self->address), xsInteger(theView), xsNull, xsString(thePath), xsInteger(theLine)); // } // } bail: // FskFileDisposeMap(map); xsThrowIfFskErr(err); }
void xs_gpio_init(xsMachine* the) { FskErr err; FskGPIO gpio; SInt32 pin = 0; GPIOdirection dir; char *pinName = NULL; xsVars(1); if ((gpio = xsGetHostData(xsThis))) xsThrowDiagnosticIfFskErr(kFskErrOperationFailed, "Digital pin %d already initialized.", (int)gpio->pinNum); dir = stringToDirection(the, xsToString(xsGet(xsThis, xsID("_direction"))), gpio); xsVar(0) = xsGet(xsThis, xsID("_pin")); if (xsStringType == xsTypeOf(xsVar(0))) pinName = xsToString(xsVar(0)); else pin = xsToInteger(xsVar(0)); err = FskGPIONew(&gpio, pin, pinName, dir); xsThrowDiagnosticIfFskErr(err, "Digital pin %d initialization failed with error %s.", pin, FskInstrumentationGetErrorString(err)); xsSetHostData(xsThis, gpio); }
void patchGrammar(xsMachine* the) { xsVars(1); xsVar(0) = xsGet(xsGlobal, xsID_Grammar); xsNewHostProperty(xsVar(0), xsID_nameToID, xsNewHostFunction(Grammar_nameToID, 1), xsDontEnum, xsDontScript); xsNewHostProperty(xsVar(0), xsID_parse, xsNewHostFunction(xs_parse, 1), xsDontEnum, xsDontScript); xsNewHostProperty(xsVar(0), xsID_stringify, xsNewHostFunction(xs_serialize, 1), xsDontEnum, xsDontScript); }
void scanStopTag(void *data, const char *name) { Scanner* self = data; xsMachine* the = self->the; scanText(data); xsArrayCacheEnd(xsVar(CHILDREN)); xsResult = xsGet(xsResult, xsID_parent); xsVar(CHILDREN) = xsGet(xsResult, xsID_children); }
void xs_console_load(xsMachine *the) { xsVars(1); xsSetInteger(xsVar(0), CONSOLE_LOG_FILE); xsSet(xsThis, xsID("LOGFILE"), xsVar(0)); xsSetInteger(xsVar(0), CONSOLE_XSBUG); xsSet(xsThis, xsID("XSBUG"), xsVar(0)); }
void xs_z_mod(xsMachine *the) { z_t *z = xsGetHostData(xsThis); xsVars(1); z_call3(the, z, kcl_z_div, &xsVar(0)); xsResult = xsVar(0); }
void KPR_message_invoke(xsMachine* the) { KprMessage self = kprGetHostData(xsThis, this, message); xsVars(1); xsVar(0) = xsNewHostFunction(KPR_Message_invoke_executor, 2); xsSet(xsVar(0), xsID_message, xsThis); if (xsToInteger(xsArgc) > 0) KprMessageScriptTargetSet(self, the, &xsArg(0)); xsResult = xsNew1(xsGlobal, xsID_Promise, xsVar(0)); }
void KPR_system_getWifiInfo(xsMachine* the) { DWORD dwResult = 0; HANDLE hClient = NULL; DWORD dwMaxClient = 2; DWORD dwCurVersion = 0; PWLAN_INTERFACE_INFO_LIST pIfList = NULL; int i; PWLAN_INTERFACE_INFO pIfInfo = NULL; DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES); PWLAN_CONNECTION_ATTRIBUTES pConnectInfo = NULL; WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid; ULONG length; xsVars(1); dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient); if (dwResult != ERROR_SUCCESS) goto bail; dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); if (dwResult != ERROR_SUCCESS) goto bail; for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) { pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i]; if (pIfInfo->isState == wlan_interface_state_connected) { dwResult = WlanQueryInterface(hClient, &pIfInfo->InterfaceGuid, wlan_intf_opcode_current_connection, NULL, &connectInfoSize, (PVOID *) &pConnectInfo, &opCode); if (dwResult != ERROR_SUCCESS) goto bail; length = pConnectInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength; if (length > 0) { xsResult = xsNewInstanceOf(xsObjectPrototype); xsVar(0) = xsStringBuffer(NULL, length + 1); FskMemCopy(xsToString(xsVar(0)), pConnectInfo->wlanAssociationAttributes.dot11Ssid.ucSSID, length); xsSet(xsResult, xsID("SSID"), xsVar(0)); } break; } } bail: if (pConnectInfo != NULL) { WlanFreeMemory(pConnectInfo); pConnectInfo = NULL; } if (pIfList != NULL) { WlanFreeMemory(pIfList); pIfList = NULL; } if (hClient != NULL) { WlanCloseHandle(hClient, NULL); hClient = NULL; } }
void parseAttributes(xsMachine* the) { xsIntegerValue c, i; if (xsTest(xsVar(CHILDREN))) { c = xsToInteger(xsGet(xsVar(CHILDREN), xsID_length)); for (i = 0; i < c; i++) { xsVar(CHILD) = xsGet(xsVar(CHILDREN), i); parseAttribute(the); } } }
void xs_z_div2(xsMachine *the) { z_t *z = xsGetHostData(xsThis); xsVars(2); z_call3(the, z, kcl_z_div, &xsVar(1)); xsVar(0) = xsResult; xsResult = xsNewInstanceOf(xsObjectPrototype); xsSet(xsResult, xsID("q"), xsVar(0)); xsSet(xsResult, xsID("r"), xsVar(1)); }
void xs_system_get_timezone(xsMachine *the) { struct timezone tz; xsVars(1); mc_gettimeofday(NULL, &tz); xsResult = xsNewInstanceOf(xsObjectPrototype); xsSetInteger(xsVar(0), tz.tz_minuteswest); xsSet(xsResult, xsID("timedifference"), xsVar(0)); xsSetInteger(xsVar(0), tz.tz_dsttime); xsSet(xsResult, xsID("dst"), xsVar(0)); }
void xs_tftpd_start(xsMachine *the) { int s; void *instance; xsVars(1); xsGet(xsVar(0), xsArg(0), xsID("nativeSocket")); s = xsToInteger(xsVar(0)); instance = tftpd_connect(s, the, &xsThis); if (instance == NULL) mc_xs_throw(the, "tftpd: no mem"); xsSetHostData(xsThis, instance); }
void scanEntity(void *data, const XML_Char *entityName, int is_parameter_entity) { Scanner* self = data; xsMachine* the = self->the; Entity* entity = (Entity*)bsearch(entityName, gxEntities, mxEntityCount, sizeof(Entity), compareEntities); if (entity) scanCharacter(data, entity->value, entity->valueLength); else { xsVar(LINE) = xsInteger(XML_GetCurrentLineNumber(self->expat)); xsVar(VALUE) = xsString((xsStringValue)entityName); xsCall3_noResult(xsThis, xsID_reportError, xsVar(PATH), xsVar(LINE), xsVar(VALUE)); scanCharacter(data, entityName, c_strlen(entityName)); } }
FskErr FskSSLNew(void **fsslp, const char *host, int port, Boolean blocking, long flags, int priority) { FskSSL *fssl; FskErr err; if ((err = FskMemPtrNewClear(sizeof(FskSSL), (FskMemPtr*)(void*)&fssl)) != kFskErrNone) return err; if ((err = newSSLVM(&fssl->vm)) != kFskErrNone) { FskMemPtrDispose(fssl); return err; } xsBeginHost(fssl->vm->the); xsTry { const char *prStr; xsVars(2); /* construct the options */ xsVar(0) = xsNewInstanceOf(xsObjectPrototype); if (blocking) xsSet(xsVar(0), xsID("blocking"), xsTrue); if (flags & kConnectFlagsSynchronous) xsSet(xsVar(0), xsID("synchronous"), xsTrue); switch (priority) { default: case kFskNetSocketLowestPriority: prStr = "lowest"; break; case kFskNetSocketLowPriority: prStr = "low"; break; case kFskNetSocketMediumPriority: prStr = "medium"; break; case kFskNetSocketHighPriority: prStr = "high"; break; case kFskNetSocketHighestPriority: prStr = "highest"; break; } (void)xsSet(xsVar(0), xsID("priority"), xsString((xsStringValue)prStr)); (void)xsSet(xsVar(0), xsID("raw"), xsTrue); xsVar(1) = xsNew3(xsGet(xsGlobal, xsID("Stream")), xsID("Socket"), xsString((xsStringValue)host), xsInteger(port), xsVar(0)); fssl->socket = xsVar(1); xsRemember(fssl->socket); xsVar(1) = xsNew0(xsGet(xsGlobal, xsID("FskSSL")), xsID("Session")); fssl->ssl = xsVar(1); xsRemember(fssl->ssl); } xsCatch { if (xsHas(xsException, xsID("code"))) err = xsToInteger(xsGet(xsException, xsID("code"))); if (err == kFskErrNone) err = kFskErrOperationFailed; } xsEndHost(fssl->vm->the); if (err == kFskErrNone) { if (fsslp != NULL) *fsslp = fssl; } else { disposeSSLVM(fssl->vm); FskMemPtrDispose(fssl); } return err; }
void KPR_canvasRadialGradient_setStyle(xsMachine *the) { FskCanvas2dContext ctx = xsGetHostData(xsArg(0)); xsNumberValue x0 = xsToNumber(xsGet(xsThis, xsID("x0"))); xsNumberValue y0 = xsToNumber(xsGet(xsThis, xsID("y0"))); xsNumberValue r0 = xsToNumber(xsGet(xsThis, xsID("r0"))); xsNumberValue x1 = xsToNumber(xsGet(xsThis, xsID("x1"))); xsNumberValue y1 = xsToNumber(xsGet(xsThis, xsID("y1"))); xsNumberValue r1 = xsToNumber(xsGet(xsThis, xsID("r1"))); UInt32 c, i; FskCanvas2dGradientStop stops[kCanvas2DMaxGradientStops]; xsVars(2); xsVar(0) = xsGet(xsThis, xsID("stops")); c = xsToInteger(xsGet(xsVar(0), xsID("length"))); if (c > kCanvas2DMaxGradientStops) c = kCanvas2DMaxGradientStops; for (i = 0; i < c; i++) { xsVar(1) = xsGetAt(xsVar(0), xsInteger(i)); stops[i].offset = xsToNumber(xsGet(xsVar(1), xsID("offset"))); xsVar(1) = xsGet(xsVar(1), xsID("color")); if (!KprParseColor(the, xsToString(xsVar(1)), &(stops[i].color))) return; } if (xsTest(xsArg(1))) FskCanvas2dSetStrokeStyleRadialGradient(ctx, x0, y0, r0, x1, y1, r1, c, stops); else FskCanvas2dSetFillStyleRadialGradient(ctx, x0, y0, r0, x1, y1, r1, c, stops); }
void xs_tftpd_connect(xsMachine *the) { int s; void *instance; xsVars(1); xsGet(xsVar(0), xsArg(0), xsID("nativeSocket")); s = xsToInteger(xsVar(0)); instance = tftpd_connect(s, the, &xsThis); if (instance == NULL) { xsSetBoolean(xsResult, 0); return; } xsSetHostData(xsThis, instance); xsSetBoolean(xsResult, 1); }
void KprMessageScriptTargetTransform(void* it, KprMessage message, xsMachine* machine) { KprMessageScriptTarget self = it; if (message->error) return; xsBeginHostSandboxCode(machine, NULL); { xsVars(2); { xsTry { void* data; UInt32 size; KprMessageGetResponseBody(message, &data, &size); if (data && size) { xsIndex id = xsID(self->name); if (xsHas(xsGlobal, id)) { xsVar(0) = xsGet(xsGlobal, id); xsVar(1) = xsNewInstanceOf(xsChunkPrototype); xsSetHostData(xsVar(1), data); xsSetHostDestructor(xsVar(1) , NULL); xsSet(xsVar(1), xsID("length"), xsInteger(size)); xsResult = xsCall1(xsVar(0), xsID("parse"), xsVar(1)); self->result = xsMarshall(xsResult); } } } xsCatch { } } } xsEndHostSandboxCode(); }
void KPR_canvasPattern_setStyle(xsMachine *the) { FskCanvas2dContext ctx = xsGetHostData(xsArg(0)); UInt32 repetition = kFskCanvas2dPatternRepeat; FskConstBitmap bitmap = NULL; Boolean owned = false; xsVars(1); xsVar(0) = xsGet(xsThis, xsID("repetition")); if (xsTest(xsVar(0))) { xsStringValue it = xsToString(xsVar(0)); if (!FskStrCompare(it, "no-repeat")) repetition = kFskCanvas2dPatternRepeatNone; else if (!FskStrCompare(it, "repeat-x")) repetition = kFskCanvas2dPatternRepeatX; else if (!FskStrCompare(it, "repeat-y")) repetition = kFskCanvas2dPatternRepeatY; else if (!FskStrCompare(it, "repeat")) repetition = kFskCanvas2dPatternRepeat; else xsError(kFskErrInvalidParameter); } xsVar(0) = xsGet(xsThis, xsID("image")); if (xsIsInstanceOf(xsVar(0), xsGet(xsGet(xsGlobal, xsID_KPR), xsID_texture))) { KprTexture texture = xsGetHostData(xsVar(0)); bitmap = KprTextureGetBitmap(texture, NULL, &owned); } else { KprContent content = xsGetHostData(xsVar(0)); bitmap = (*content->dispatch->getBitmap)(content, NULL, &owned); } if (!bitmap) xsError(kFskErrInvalidParameter); if (xsTest(xsArg(1))) FskCanvas2dSetStrokeStylePattern(ctx, repetition, bitmap); else FskCanvas2dSetFillStylePattern(ctx, repetition, bitmap); if (!owned) FskBitmapDispose((FskBitmap)bitmap); }
void KPR_debug_get_machines(xsMachine *the) { KprDebug self = xsGetHostData(xsThis); KprDebugMachine machine = NULL; xsEnterSandbox(); xsVars(1); { xsResult = xsNewInstanceOf(xsArrayPrototype); for (machine = self->machine; machine; machine = machine->next) { xsVar(0) = xsNewInstanceOf(xsObjectPrototype); xsNewHostProperty(xsVar(0), xsID("address"), xsString(machine->address), xsDefault, xsDontScript); if (machine->title) xsNewHostProperty(xsVar(0), xsID("title"), xsString(machine->title), xsDefault, xsDontScript); xsCall1(xsResult, xsID_push, xsVar(0)); } } xsLeaveSandbox(); }
void Zeroconf_advertisement_callback(KprZeroconfAdvertisement self, char* function) { xsBeginHostSandboxCode(self->the, self->code); if (xsTypeOf(self->behavior) == xsUndefinedType) goto bail; xsVars(2); { xsTry { xsVar(0) = xsAccess(self->behavior); xsVar(1) = xsAccess(self->slot); if (xsFindResult(xsVar(0), xsID(function))) { (void)xsCallFunction1(xsResult, xsVar(0), xsVar(1)); } } xsCatch { } } bail: xsEndHostSandboxCode(); }
void KprDebugMachineUnlockView(KprDebugMachine self, int theView) { KprDebug debug = self->debug; xsMachine* the = debug->the; // FskDebugStr("%s: %d", __FUNCTION__, theView); if (xsTypeOf(debug->behavior) == xsUndefinedType) goto bail; { xsTry { xsVar(0) = xsAccess(debug->behavior); xsVar(1) = xsGet(xsVar(0), xsID(self->address)); KprDebugMachineCallbackView(self, "onMachineViewChanged", theView); } xsCatch { } } bail: return; }
FskErr FskSSLLoadCerts(void *a, FskSocketCertificateRecord *cert) { FskSSL *fssl = a; FskErr err = kFskErrNone; xsBeginHost(fssl->vm->the); xsTry { xsVars(2); xsVar(0) = xsUndefined; xsVar(1) = xsUndefined; if (cert != NULL) { if (cert->certificates != NULL && cert->certificatesSize > 0) { xsVar(0) = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(cert->certificatesSize)); FskMemCopy(xsGetHostData(xsVar(0)), cert->certificates, cert->certificatesSize); } if (cert->policies != NULL) { if (cert->certificates == NULL) xsVar(0) = xsNew0(xsGlobal, xsID("Chunk")); // create a null chunk just for setting the polices xsSet(xsVar(0), xsID("policies"), xsString(cert->policies)); } if (cert->hostname != NULL) { xsSet(fssl->socket, xsID("hostname"), xsString(cert->hostname)); // too easy but should work... } if (cert->key != NULL && cert->keySize > 0) { xsVar(1) = xsNew1(xsGlobal, xsID("Chunk"), xsInteger(cert->keySize)); FskMemCopy(xsGetHostData(xsVar(1)), cert->key, cert->keySize); } } xsCall2_noResult(fssl->ssl, xsID("loadCerts"), xsVar(0), xsVar(1)); } xsCatch { if (xsHas(xsException, xsID("code"))) err = xsToInteger(xsGet(xsException, xsID("code"))); if (err == kFskErrNone) err = kFskErrOperationFailed; } xsEndHost(fssl->vm->the); return err; }
void KprDebugMachineSetViewTitle(KprDebugMachine self, int theView, char* theTitle) { KprDebug debug = self->debug; xsMachine* the = debug->the; // FskDebugStr("%s: %d - %s", __FUNCTION__, theView, theTitle); if (xsTypeOf(debug->behavior) == xsUndefinedType) goto bail; { xsTry { xsVar(0) = xsAccess(debug->behavior); xsVar(1) = xsGet(xsVar(0), xsID(self->address)); if (xsFindResult(xsVar(0), xsID("onMachineViewTitle"))) (void)xsCallFunction3(xsResult, xsVar(0), xsString(self->address), xsInteger(theView), xsString(theTitle)); } xsCatch { } } bail: return; }
void xs_dbg_report(xsMachine *the) { if (xsToInteger(xsArgc) > 0 && xsTest(xsArg(0))) { /* silence - return the memory use */ xsMemoryUse slot, chunk; xsReportMemoryUse(the, &slot, &chunk); xsVars(1); xsResult = xsNewInstanceOf(xsObjectPrototype); xsSetInteger(xsVar(0), chunk.current); xsSet(xsResult, xsID("chunk"), xsVar(0)); xsSetInteger(xsVar(0), slot.current); xsSet(xsResult, xsID("slot"), xsVar(0)); } else { #if mxMC mc_mstats(true); #endif xsReportMemoryUse(the, NULL, NULL); } }
void xs_infoset_parse(xsMachine* the) { xsVars(COUNT); xsVar(ATTRIBUTE_PROTOTYPE) = xsGet(xsThis, xsID_attribute); xsVar(CDATA_PROTOTYPE) = xsGet(xsThis, xsID_cdata); xsVar(COMMENT_PROTOTYPE) = xsGet(xsThis, xsID_comment); xsVar(DOCUMENT_PROTOTYPE) = xsGet(xsThis, xsID_document); xsVar(ELEMENT_PROTOTYPE) = xsGet(xsThis, xsID_element); if ((xsToInteger(xsArgc) < 1) || (!xsIsInstanceOf(xsArg(0), xsVar(DOCUMENT_PROTOTYPE)))) xsTypeError("document is no infoset.document"); xsVar(RULE_SET) = xsGet(xsGet(xsGlobal, xsID_Grammar), xsID_ruleSet); xsVar(CHILD) = xsGet(xsArg(0), xsID_element); parseElement(the); }
FskErr FskSSLHandshake(void *a, FskNetSocketCreatedCallback callback, void *refCon, Boolean initiate) { FskSSL *fssl = a; FskErr err = kFskErrNone; fssl->socketCallback = callback; fssl->callbackData = refCon; xsBeginHost(fssl->vm->the); xsTry { xsVars(1); /* set session._hostData = ssl, just for callback */ xsVar(0) = xsNewHostObject(NULL); xsSetHostData(xsVar(0), fssl); xsSet(fssl->ssl, xsID("_hostData"), xsVar(0)); xsVar(0) = xsNewHostFunction(xs_handshake_finished_callback, 2); xsSet(fssl->ssl, xsID("_hostCallback"), xsVar(0)); xsCall3_noResult(fssl->ssl, xsID("handshake"), fssl->socket, xsVar(0), initiate ? xsTrue : xsFalse); } xsCatch { if (xsHas(xsException, xsID("code"))) err = xsToInteger(xsGet(xsException, xsID("code"))); if (err == kFskErrNone) err = kFskErrOperationFailed; } xsEndHost(fssl->vm->the); return err; }
void KPR_host_quitting(xsMachine* the) { KprContainer container = xsGetHostData(xsThis); KprContent content = container->first; KprScriptBehavior self = (KprScriptBehavior)content->behavior; #if SUPPORT_INSTRUMENTATION void* params[2] = { self, "xsID_onQuitting" }; FskInstrumentedItemSendMessageDebug(content, kprInstrumentedContentCallBehavior, params); #endif if (self) { xsBeginHostSandboxCode(self->the, self->code); { xsVars(2); xsVar(0) = xsAccess(self->slot); if (xsFindResult(xsVar(0), xsID_onQuitting)) { xsVar(1) = kprContentGetter(content); (void)xsCallFunction1(xsResult, xsVar(0), xsVar(1)); } } xsEndHostSandboxCode(); } }
void KprDebugMachineCallbackText(KprDebugMachine machine, char* function, int view, char* text) { KprDebug self = machine->debug; xsMachine* the = self->the; if (xsTypeOf(self->behavior) == xsUndefinedType) goto bail; { xsTry { xsVar(0) = xsAccess(self->behavior); if (xsFindResult(xsVar(0), xsID(function))) { if (view >= 0) (void)xsCallFunction3(xsResult, xsVar(0), xsString(machine->address), xsInteger(view), xsString(text)); else if (text) (void)xsCallFunction2(xsResult, xsVar(0), xsString(machine->address), xsString(text)); else (void)xsCallFunction1(xsResult, xsVar(0), xsString(machine->address)); } } xsCatch { } } bail: return; }
void xs_pwm_init(xsMachine* the) { FskErr err; FskPinPWM pwm; SInt32 pin = 0; char *pinName = NULL; xsVars(1); pwm = xsGetHostData(xsThis); if (pwm) xsThrowDiagnosticIfFskErr(kFskErrBadState, "PWM pin %d already initialized.", (int)pin); xsVar(0) = xsGet(xsThis, xsID("pin")); if (xsStringType == xsTypeOf(xsVar(0))) pinName = xsToString(xsVar(0)); else pin = xsToInteger(xsVar(0)); err = FskPinPWMNew(&pwm, pin, pinName); xsThrowDiagnosticIfFskErr(err, "PWM initialization of pin %d failed with error %d.", (int)pin, FskInstrumentationGetErrorString(err)); xsSetHostData(xsThis, pwm); }