Example #1
0
void fx_Error_toString(txMachine* the)
{
	txInteger aLength;
	
	mxPushSlot(mxThis);
	fxGetID(the, mxID(_name));
	if (the->stack->kind == XS_UNDEFINED_KIND) 
		fxCopyStringC(the, the->stack, "Error");
	else	
		fxToString(the, the->stack);
	mxPushSlot(mxThis);
	fxGetID(the, mxID(_message));
	if (the->stack->kind == XS_UNDEFINED_KIND) 
		fxCopyStringC(the, the->stack, "");
	else	
		fxToString(the, the->stack);
	aLength = c_strlen(the->stack->value.string);
	if (aLength) {
		aLength += c_strlen((the->stack + 1)->value.string) + 2;
		mxResult->value.string = (txString)fxNewChunk(the, aLength + 1);
		mxResult->kind = XS_STRING_KIND;
		c_strcpy(mxResult->value.string, (the->stack + 1)->value.string);
		c_strcat(mxResult->value.string, ": ");
		c_strcat(mxResult->value.string, the->stack->value.string);
		the->stack++;
		the->stack++;
	}
	else {
		the->stack++;
		mxPullSlot(mxResult);
	}
}
Example #2
0
void luaO_chunkid (char *out, const char *source, size_t bufflen) {
  if (*source == '=') {
    c_strncpy(out, source+1, bufflen);  /* remove first char */
    out[bufflen-1] = '\0';  /* ensures null termination */
  }
  else {  /* out = "source", or "...source" */
    if (*source == '@') {
      size_t l;
      source++;  /* skip the `@' */
      bufflen -= sizeof(" '...' ");
      l = c_strlen(source);
      c_strcpy(out, "");
      if (l > bufflen) {
        source += (l-bufflen);  /* get last part of file name */
        c_strcat(out, "...");
      }
      c_strcat(out, source);
    }
    else {  /* out = [string "string"] */
      size_t len = c_strcspn(source, "\n\r");  /* stop at first newline */
      bufflen -= sizeof(" [string \"...\"] ");
      if (len > bufflen) len = bufflen;
      c_strcpy(out, "[string \"");
      if (source[len] != '\0') {  /* must truncate? */
        c_strncat(out, source, len);
        c_strcat(out, "...");
      }
      else
        c_strcat(out, source);
      c_strcat(out, "\"]");
    }
  }
}
Example #3
0
txModuleData* fxLoadLibrary(txMachine* the, txString path, txScript* script)
{
	txModuleData* data = C_NULL;
	if (script) {
		if (script->version[3] == 1) {
			char buffer[PATH_MAX];
			char* dot;
			void* library;
			txCallback callback;
			c_strcpy(buffer, path);
			dot = c_strrchr(buffer, '.');
			if (dot)
				*dot = 0;
			#if mxWindows
				c_strcat(buffer, ".dll");
				#if mxReport
					fxReport(the, "# Loading library \"%s\"\n", buffer);
				#endif
				library = LoadLibrary(buffer);
				mxElseError(library);
				callback = (txCallback)GetProcAddress(library, "xsHostModule");
				mxElseError(callback);
			#else
				c_strcat(buffer, ".so");
				#if mxReport
					fxReport(the, "# Loading library \"%s\"\n", buffer);
				#endif
				library = dlopen(buffer, RTLD_NOW);
				mxElseError(library);
				callback = (txCallback)dlsym(library, "xsHostModule");
				mxElseError(callback);
			#endif
			data = c_malloc(sizeof(txModuleData) + c_strlen(buffer));
			mxElseError(data);
			data->library = library;
			data->the = the;
			c_strcpy(data->path, buffer);
			script->callback = callback;
			return data;
		}
	}
#if mxReport
	data = c_malloc(sizeof(txModuleData) + c_strlen(path));
	mxElseError(data);
	data->library = C_NULL;
	data->the = the;
	c_strcpy(data->path, path);
	fxReport(the, "# Loading module \"%s\"\n", path);
#endif
	return data;
}
Example #4
0
void fx_Error_toString(txMachine* the)
{
	txSlot* anError;
	txSlot* aProperty;
	txInteger aLength;
	
	anError = fxGetInstance(the, mxThis);
	aProperty = fxGetProperty(the, anError, fxID(the, "name"));
	--the->stack;
	the->stack->kind = aProperty->kind;
	the->stack->value = aProperty->value;
	if (the->stack->kind == XS_UNDEFINED_KIND) 
		fxCopyStringC(the, the->stack, "Error");
	else	
		fxToString(the, the->stack);
	aProperty = fxGetProperty(the, anError, fxID(the, "message"));
	--the->stack;
	the->stack->kind = aProperty->kind;
	the->stack->value = aProperty->value;
	if (the->stack->kind == XS_UNDEFINED_KIND) 
		fxCopyStringC(the, the->stack, "");
	else	
		fxToString(the, the->stack);
	aLength = c_strlen(the->stack->value.string);
	if (aLength) {
		aLength += c_strlen((the->stack + 1)->value.string) + 2;
		mxResult->value.string = (txString)fxNewChunk(the, aLength + 1);
		mxResult->kind = XS_STRING_KIND;
		c_strcpy(mxResult->value.string, (the->stack + 1)->value.string);
		c_strcat(mxResult->value.string, ": ");
		c_strcat(mxResult->value.string, the->stack->value.string);
		the->stack++;
		the->stack++;
	}
	else {
		the->stack++;
		*mxResult = *(the->stack++);
	}
}
Example #5
0
void fxIncludeScript(txParser* parser, txString string) 
{
	txSymbol* symbol = parser->path;
	char buffer[PATH_MAX];
	char include[PATH_MAX];
	FILE* file = NULL;
	c_strcpy(include, string);
	c_strcat(include, ".js");
	fxMergePath(symbol->string, include, buffer);
	mxParserThrowElse(realpath(buffer, include));
	parser->path = fxNewParserSymbol(parser, include);
	file = fopen(include, "r");
	mxParserThrowElse(file);
	fxParserTree(parser, file, (txGetter)fgetc, parser->flags, NULL);
	fclose(file);
	file = NULL;
	parser->path = symbol;
}
Example #6
0
void fx_String_concat(txMachine* the)
{
	txString aString;
	txInteger aCount;
	txInteger aLength;
	txInteger anIndex;
	
	aString = fxCoerceToString(the, mxThis);
	if (!aString)
		mxDebug0(the, XS_TYPE_ERROR, "String.prototype.concat: this is null or undefined");
	aCount = mxArgc;
	aLength = c_strlen(mxThis->value.string);
	for (anIndex = 0; anIndex < aCount; anIndex++)
		aLength += c_strlen(fxToString(the, mxArgv(anIndex)));
	mxResult->value.string = (txString)fxNewChunk(the, aLength + 1);
	mxResult->kind = XS_STRING_KIND;
	c_strcpy(mxResult->value.string, mxThis->value.string);
	for (anIndex = 0; anIndex < aCount; anIndex++)
		c_strcat(mxResult->value.string, mxArgv(anIndex)->value.string);
}
Example #7
0
void* fxMapArchive(txString base, txCallbackAt callbackAt)
{
	int error = 0;
	txArchive* archive = C_NULL;
#if mxWindows
#else
	struct stat statbuf;
#endif
	txString p;
	Atom atom;
	int c, i;
	txString* symbol;
	txScript* script;

	archive = c_malloc(sizeof(txArchive));
	bailElse(archive);
	c_memset(archive, 0, sizeof(txArchive));
	c_strcpy(archive->base, base);
#if mxWindows
	archive->file = CreateFile(base, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	bailElse(archive->file != INVALID_HANDLE_VALUE);
	archive->size = GetFileSize(archive->file, &archive->size);
	bailElse(archive->size != INVALID_FILE_SIZE);
	archive->mapping = CreateFileMapping(archive->file, NULL, PAGE_READONLY, 0, (SIZE_T)archive->size, NULL);
	bailElse(archive->mapping != INVALID_HANDLE_VALUE);
	archive->address = MapViewOfFile(archive->mapping, FILE_MAP_READ, 0, 0, (SIZE_T)archive->size);
	bailElse(archive->address != NULL);
#else
	archive->fd = open(base, O_RDONLY);
	bailElse(archive->fd >= 0);
	fstat(archive->fd, &statbuf);
	archive->size = statbuf.st_size;
	archive->address = mmap(NULL, archive->size, PROT_READ, MAP_SHARED, archive->fd, 0);
	bailElse(archive->address != MAP_FAILED);
#endif
	p = archive->address;
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_ARCHIVE);
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_VERSION);
	bailAssert(*p++ == XS_MAJOR_VERSION);
	bailAssert(*p++ == XS_MINOR_VERSION);
	bailAssert(*p++ == XS_PATCH_VERSION);
	if ((*p++) && !callbackAt) {
		char* dot;
		dot = c_strrchr(archive->base, '.');
		if (dot)
			*dot = 0;
		#if mxWindows
			c_strcat(archive->base, ".dll");
			archive->library = LoadLibrary(archive->base);
			bailElse(archive->library);
			callbackAt = (txCallbackAt)GetProcAddress(archive->library, "xsHostModuleAt");
			bailElse(callbackAt);
		#else
			c_strcat(archive->base, ".so");
			archive->library = dlopen(archive->base, RTLD_NOW);
			if (!archive->library)
        		fprintf(stderr, "%s\n", dlerror());
			bailElse(archive->library);
			callbackAt = (txCallbackAt)dlsym(archive->library, "xsHostModuleAt");
			bailElse(callbackAt);
		#endif
		archive->keys = callbackAt(0);
	}
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_SYMBOLS);
	c = archive->symbolCount = ntohs(*((unsigned short*)p));
	p += 2;
	if (c) {
		symbol = archive->symbols = c_malloc(c * sizeof(txString));
		for (i = 0; i < c; i++) {
			*symbol = p;
			p += c_strlen(p) + 1;
			symbol++;
		}
	}
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_PATHS);
	c = archive->scriptCount = ntohs(*((unsigned short*)p));
	p += 2;
	script = archive->scripts = c_malloc(c * sizeof(txScript));
	c_memset(script, 0, c * sizeof(txScript));
	for (i = 1; i <= c; i++) {
		if (callbackAt)
			script->callback = callbackAt(i);
		script->path = p;
		p += c_strlen(p) + 1;
		script++;
	}
	
	script = archive->scripts;
	for (i = 0; i < c; i++) {
		p = fxMapAtom(p, &atom);
		bailAssert(atom.atomType == XS_ATOM_CODE);
		script->codeSize = atom.atomSize - sizeof(atom);
		script->codeBuffer = (txS1*)p;
		p += script->codeSize;
		script++;
	}
	
	p = c_strrchr(archive->base, mxSeparator);
	if (p) {
		p++;
		*p = 0;
		archive->baseLength = p - archive->base;
	}
bail:
	if (error) {
		fxUnmapArchive(archive);
		archive = C_NULL;
	}
	return archive;
}
Example #8
0
int main(int argc, char* argv[]) 
{
	int argi;
	txString base = NULL;
    txString output = NULL;
	txString input = NULL;
	char name[PATH_MAX];
	char path[PATH_MAX];
	txLinker _linker;
	txLinker* linker = &_linker;
	txInteger modulo = 0;
	txLinkerScript** link;
	txLinkerScript* script;
	FILE* file = C_NULL;
	txSize size;
	txByte byte;
	
	fxInitializeLinker(linker);
	if (c_setjmp(linker->jmp_buf) == 0) {
		c_strcpy(name, "a");
		link = &(linker->firstScript);
		for (argi = 1; argi < argc; argi++) {
			if (!c_strcmp(argv[argi], "-a")) {
				argi++;
				c_strncpy(name, argv[argi], sizeof(name));
			}
			else if (!c_strcmp(argv[argi], "-b")) {
				argi++;
				if (argi >= argc)
					fxReportError(linker, "-b: no directory");
				base = fxRealDirectoryPath(linker, argv[argi]);
				if (!base)
					fxReportError(linker, "-b '%s': directory not found", argv[argi]);
			}
			else if (!c_strcmp(argv[argi], "-o")) {
				argi++;
				if (argi >= argc)
					fxReportError(linker, "-o: no directory");
				output = fxRealDirectoryPath(linker, argv[argi]);
				if (!output)
					fxReportError(linker, "-o '%s': directory not found", argv[argi]);
			}
			else if (!c_strcmp(argv[argi], "-r")) {
				argi++;
				if (argi >= argc)
					fxReportError(linker, "-r: no modulo");
				modulo = (txInteger)fxStringToNumber(linker->dtoa, argv[argi], 1);
				if (modulo <= 0)
					fxReportError(linker, "-r: invalid modulo");
				linker->symbolModulo = modulo;
			}
			else {
				input = fxRealFilePath(linker, argv[argi]);
				if (!input)
					fxReportError(linker, "'%s': file not found", argv[argi]);
				fxLoadScript(linker, input, link, &file);
				link = &((*link)->nextScript);
			}
		}
		if (!output)
			output = fxRealDirectoryPath(linker, ".");
		if (!base)
			base = output;
		linker->symbolTable = fxNewLinkerChunkClear(linker, linker->symbolModulo * sizeof(txSymbol*));
		
		c_strcpy(path, output);
		c_strcat(path, name);
		c_strcat(path, ".xsa");
		if (!modulo && fxRealFilePath(linker, path))
			fxLoadArchive(linker, path, &file);
			
		size = c_strlen(base);
		script = linker->firstScript;
		while (script) {
			fxBaseScript(linker, script, base, size);
			script = script->nextScript;
		}
		fxBufferPaths(linker);
	
		fxDefaultSymbols(linker);
		script = linker->firstScript;
		while (script) {
			fxMapScript(linker, script);
			script = script->nextScript;
		}
		fxBufferSymbols(linker, modulo);
		
		file = fopen(path, "wb");
		mxThrowElse(file);
		size = 8 + 8 + 4 + 8 + linker->symbolsSize + 8 + linker->pathsSize + (8 * linker->scriptCount) + linker->codeSize;
		size = htonl(size);
		mxThrowElse(fwrite(&size, 4, 1, file) == 1);
		mxThrowElse(fwrite("XS6A", 4, 1, file) == 1);

		size = 8 + 4;
		size = htonl(size);
		mxThrowElse(fwrite(&size, 4, 1, file) == 1);
		mxThrowElse(fwrite("VERS", 4, 1, file) == 1);
		byte = XS_MAJOR_VERSION;
		mxThrowElse(fwrite(&byte, 1, 1, file) == 1);
		byte = XS_MINOR_VERSION;
		mxThrowElse(fwrite(&byte, 1, 1, file) == 1);
		byte = XS_PATCH_VERSION;
		mxThrowElse(fwrite(&byte, 1, 1, file) == 1);
		byte = (linker->hostsCount) ? 1 : 0;
		mxThrowElse(fwrite(&byte, 1, 1, file) == 1);

		size = 8 + linker->symbolsSize;
		size = htonl(size);
		mxThrowElse(fwrite(&size, 4, 1, file) == 1);
		mxThrowElse(fwrite("SYMB", 4, 1, file) == 1);
		mxThrowElse(fwrite(linker->symbolsBuffer, linker->symbolsSize, 1, file) == 1);

		size = 8 + linker->pathsSize;
		size = htonl(size);
		mxThrowElse(fwrite(&size, 4, 1, file) == 1);
		mxThrowElse(fwrite("PATH", 4, 1, file) == 1);
		mxThrowElse(fwrite(linker->pathsBuffer, linker->pathsSize, 1, file) == 1);

		script = linker->firstScript;
		while (script) {
			size = 8 + script->codeSize;
			size = htonl(size);
			mxThrowElse(fwrite(&size, 4, 1, file) == 1);
			mxThrowElse(fwrite("CODE", 4, 1, file) == 1);
			mxThrowElse(fwrite(script->codeBuffer, script->codeSize, 1, file) == 1);
			script = script->nextScript;
		}
		fclose(file);
		file = NULL;
		
		if (linker->hostsCount || modulo) {
			c_strcpy(path, base);
			c_strcat(path, name);
			c_strcat(path, ".xs.h");
			file = fopen(path, "w");
			mxThrowElse(file);
			fprintf(file, "/* XS GENERATED FILE; DO NOT EDIT! */\n\n");
			fprintf(file, "#include <xs.h>\n\n");
			fxWriteExterns(linker, file);
			fxWriteIDs(linker, file);
			fclose(file);
			file = NULL;
		
			c_strcpy(path, base);
			c_strcat(path, name);
			c_strcat(path, ".xs.c");
			file = fopen(path, "w");
			mxThrowElse(file);
			fprintf(file, "/* XS GENERATED FILE; DO NOT EDIT! */\n\n");
			if (modulo)
				fprintf(file, "#include <xs6All.h>\n\n");
			fprintf(file, "#include \"%s.xs.h\"\n\n", name);
			if (modulo) {
				txS2 c, i;
				txSymbol** address;
				c = (txS2)(linker->symbolIndex);
				address = &(linker->symbolArray[0]);
				for (i = 0; i < c; i++) {
					txSymbol* symbol = *address;
					fprintf(file, "static const txSlot xs_key_%d = {\n", symbol->ID & 0x7FFF);
					if (symbol->next)
						fprintf(file, "\t(txSlot *)&xs_key_%d,\n", symbol->next->ID & 0x7FFF);
					else
						fprintf(file, "\tNULL,\n");
					if (i < XS_SYMBOL_ID_COUNT) {
						fprintf(file, "\tXS_NO_ID, XS_DONT_ENUM_FLAG | XS_MARK_FLAG, XS_STRING_X_KIND,\n");
						fprintf(file, "\t{ .string = \"");
						fxWriteSymbolString(linker, file, symbol->string);
						fprintf(file, "\" }\n");
					}
					else {
						fprintf(file, "\t%d, XS_DONT_ENUM_FLAG | XS_MARK_FLAG, XS_KEY_X_KIND,\n", (int)symbol->ID);
						fprintf(file, "\t{ .key = {\"");
						fxWriteSymbolString(linker, file, symbol->string);
						fprintf(file, "\", 0x%X} }\n", (int)symbol->sum);
					}
					fprintf(file, "};\n");
					address++;
				}
				fprintf(file, "static const txSlot *xs_keys[%d] = {\n", c);
				address = &(linker->symbolArray[0]);
				for (i = 0; i < c; i++) {
					txSymbol* symbol = *address;
					fprintf(file, "\t&xs_key_%d,\n", symbol->ID & 0x7FFF);
					address++;
				}
				fprintf(file, "};\n\n");
			
				fprintf(file, "static void xsHostKeys(txMachine* the)\n");
				fprintf(file, "{\n");
				fprintf(file, "\ttxSlot* code = &mxIDs;\n");
				fprintf(file, "\ttxInteger i;\n");
				fprintf(file, "\tmxCheck(the, the->nameModulo == %ld);\n", modulo);
				fprintf(file, "\tcode->value.code = (txByte *)fxNewChunk(the, %d * sizeof(txID));\n", c);
				fprintf(file, "\tcode->kind = XS_CODE_KIND;\n");
				fprintf(file, "\tfor (i = 0; i < XS_SYMBOL_ID_COUNT; i++) {\n");
				fprintf(file, "\t\ttxSlot *description = (txSlot *)xs_keys[i];\n");
				fprintf(file, "\t\tthe->keyArray[i] = description;\n");
				fprintf(file, "\t\tmxID(i) = 0x8000 | i;\n");
				fprintf(file, "\t}\n");
				fprintf(file, "\tfor (; i < %d; i++) {\n",  c);
				fprintf(file, "\t\ttxSlot *key = (txSlot *)xs_keys[i];\n");
				fprintf(file, "\t\tthe->keyArray[i] = key;\n");
				fprintf(file, "\t\tthe->nameTable[key->value.key.sum %% %ld] = key;\n", modulo);
				fprintf(file, "\t\tmxID(i) = key->ID;\n");
				fprintf(file, "\t}\n");
				fprintf(file, "\tthe->keyIndex = %d;\n", c);
				fprintf(file, "\tthe->keyOffset = %d;\n", c);
				fprintf(file, "}\n\n");
			}
			fxWriteHosts(linker, file, modulo);
			fclose(file);
			file = NULL;
		}
		
	}
	else {
		if (linker->error != C_EINVAL) {
		#if mxWindows
			char buffer[2048];
			FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, linker->error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL);
			fprintf(stderr, "### %s\n", buffer);
		#else
			fprintf(stderr, "### %s\n", strerror(linker->error));
		#endif
		}
	}
	if (file)
		fclose(file);
	fxTerminateLinker(linker);
	return linker->error;
}
Example #9
0
void* fxMapArchive(txString base, txCallbackAt callbackAt)
{
	FskErr err = kFskErrNone;
	txArchive* archive = NULL;
	txString p;
	Atom atom;
	int c, i;
	txString* symbol;
	txScript* script;

	bailIfError(FskMemPtrNewClear(sizeof(txArchive), &archive));
	c_strcpy(archive->base, base);
	bailIfError(FskFileMap(base, (unsigned char**)&(archive->address), &(archive->size), 0, &(archive->map)));

	p = archive->address;
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_ARCHIVE);
	
	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_VERSION);
	bailAssert(*p++ == XS_MAJOR_VERSION);
	bailAssert(*p++ == XS_MINOR_VERSION);
	bailAssert(*p++ == XS_PATCH_VERSION);
	if ((*p++) && !callbackAt) {
		char* dot;
		dot = c_strrchr(archive->base, '.');
		if (dot)
			*dot = 0;
		#if mxWindows
			c_strcat(archive->base, ".dll");
		#else
			c_strcat(archive->base, ".so");
		#endif
		bailIfError(FskLibraryLoad(&(archive->library), archive->base));
		bailIfError(FskLibraryGetSymbolAddress(archive->library, "xsHostModuleAt", &callbackAt));
		archive->keys = callbackAt(0);
	}

	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_SYMBOLS);
	mxDecode2(p, archive->symbolCount);
	c = archive->symbolCount;
	if (c) {
		bailIfError(FskMemPtrNew(c * sizeof(txString), &(archive->symbols)));
		symbol = archive->symbols;
		for (i = 0; i < c; i++) {
			*symbol = p;
			p += c_strlen(p) + 1;
			symbol++;
		}
	}

	p = fxMapAtom(p, &atom);
	bailAssert(atom.atomType == XS_ATOM_PATHS);
	mxDecode2(p, archive->scriptCount);
	c = archive->scriptCount;
	bailIfError(FskMemPtrNewClear(c * sizeof(txScript), &(archive->scripts)));
	script = archive->scripts;
	for (i = 1; i <= c; i++) {
		if (callbackAt)
			script->callback = callbackAt(i);
		script->path = p;
		bailIfNULL(script->path);
		p += c_strlen(p) + 1;
		script++;
	}
	
	script = archive->scripts;
	for (i = 0; i < c; i++) {
		p = fxMapAtom(p, &atom);
		bailAssert(atom.atomType == XS_ATOM_CODE);
		script->codeSize = atom.atomSize - sizeof(atom);
		script->codeBuffer = (txS1*)p;
		p += script->codeSize;
		script++;
	}
	
	p = c_strrchr(archive->base, '/');
	if (p) {
		p++;
		*p = 0;
		archive->baseLength = p - archive->base;
	}
bail:
	if (err) {
		fxUnmapArchive(archive);
		archive = NULL;
	}
	return archive;
}