Skip to content

Commit

Permalink
MSVC compatibility
Browse files Browse the repository at this point in the history
1. MSVC compatibility
2. CONFIG_VERSION (too common/generic) replaced by QUICKJS_VERSION due to clashes with other libraries that use CONFIG_VERSION too
  • Loading branch information
c-smile committed Oct 12, 2020
1 parent 7c312df commit 4298c1a
Show file tree
Hide file tree
Showing 16 changed files with 4,127 additions and 27 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# OS generated files
## Mac OS X
.DS_Store
.Trashes
.Spotlight-V100
# # Windows
Thumbs.db
.bin
.build
26 changes: 25 additions & 1 deletion cutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,30 @@

#include "cutils.h"

#ifdef _MSC_VER

// From: https://stackoverflow.com/a/26085827
int gettimeofday(struct timeval * tp, struct timezone * tzp)
{
static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);

SYSTEMTIME system_time;
FILETIME file_time;
uint64_t time;

GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
time = ((uint64_t)file_time.dwLowDateTime);
time += ((uint64_t)file_time.dwHighDateTime) << 32;

tp->tv_sec = (long)((time - EPOCH) / 10000000L);
tp->tv_usec = (long)(system_time.wMilliseconds * 1000);

return 0;
}
#endif


void pstrcpy(char *buf, int buf_size, const char *str)
{
int c;
Expand Down Expand Up @@ -297,7 +321,7 @@ int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
return -1;
c = (c << 6) | (b & 0x3f);
}
if (c < utf8_min_code[l - 1])
if (c < (int)utf8_min_code[l - 1])
return -1;
*pp = p;
return c;
Expand Down
97 changes: 90 additions & 7 deletions cutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,32 @@
#include <stdlib.h>
#include <inttypes.h>

#ifdef _MSC_VER
#include <windows.h>
#include <intrin.h>
#else
#include <sys/time.h>
#endif

/* set if CPU is big endian */
#undef WORDS_BIGENDIAN

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define force_inline inline __attribute__((always_inline))
#define no_inline __attribute__((noinline))
#define __maybe_unused __attribute__((unused))
#ifndef __has_attribute
#define likely(x) (x)
#define unlikely(x) (x)
#define force_inline __forceinline
#define no_inline __declspec(noinline)
#define __maybe_unused
#define __attribute__(x)
#define __attribute(x)
typedef size_t ssize_t;
#else
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define force_inline inline __attribute__((always_inline))
#define no_inline __attribute__((noinline))
#define __maybe_unused __attribute__((unused))
#endif

#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
Expand Down Expand Up @@ -114,27 +132,91 @@ static inline int64_t min_int64(int64_t a, int64_t b)
/* WARNING: undefined if a = 0 */
static inline int clz32(unsigned int a)
{
#ifdef _MSC_VER
unsigned long idx;
_BitScanReverse(&idx, a);
return 31 ^ idx;
#else
return __builtin_clz(a);
#endif
}

/* WARNING: undefined if a = 0 */
static inline int clz64(uint64_t a)
{
return __builtin_clzll(a);
#ifdef _MSC_VER
unsigned long where;
// BitScanReverse scans from MSB to LSB for first set bit.
// Returns 0 if no set bit is found.
#if INTPTR_MAX >= INT64_MAX // 64-bit
if (_BitScanReverse64(&where, a))
return (int)(63 - where);
#else
// Scan the high 32 bits.
if (_BitScanReverse(&where, (uint32_t)(a >> 32)))
return (int)(63 - (where + 32)); // Create a bit offset from the MSB.
// Scan the low 32 bits.
if (_BitScanReverse(&where, (uint32_t)(a)))
return (int)(63 - where);
#endif
return 64; // Undefined Behavior.
#else
return __builtin_clzll(a);
#endif
}

/* WARNING: undefined if a = 0 */
static inline int ctz32(unsigned int a)
{
#ifdef _MSC_VER
unsigned long idx;
_BitScanForward(&idx, a);
return 31 ^ idx;
#else
return __builtin_ctz(a);
#endif
}

/* WARNING: undefined if a = 0 */
static inline int ctz64(uint64_t a)
{
return __builtin_ctzll(a);
#ifdef _MSC_VER
unsigned long where;
// Search from LSB to MSB for first set bit.
// Returns zero if no set bit is found.
#if INTPTR_MAX >= INT64_MAX // 64-bit
if (_BitScanForward64(&where, a))
return (int)(where);
#else
// Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
// Scan the Low Word.
if (_BitScanForward(&where, (uint32_t)(a)))
return (int)(where);
// Scan the High Word.
if (_BitScanForward(&where, (uint32_t)(a >> 32)))
return (int)(where + 32); // Create a bit offset from the LSB.
#endif
return 64;
#else
return __builtin_ctzll(a);
#endif
}

#ifdef _MSC_VER
#pragma pack(push, 1)
struct packed_u64 {
uint64_t v;
};

struct packed_u32 {
uint32_t v;
};

struct packed_u16 {
uint16_t v;
};
#pragma pack(pop)
#else
struct __attribute__((packed)) packed_u64 {
uint64_t v;
};
Expand All @@ -146,6 +228,7 @@ struct __attribute__((packed)) packed_u32 {
struct __attribute__((packed)) packed_u16 {
uint16_t v;
};
#endif

static inline uint64_t get_u64(const uint8_t *tab)
{
Expand Down
2 changes: 1 addition & 1 deletion libregexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ static int parse_digits(const uint8_t **pp, BOOL allow_overflow)
p++;
}
*pp = p;
return v;
return (int)v;
}

static int re_parse_expect(REParseState *s, const uint8_t **pp, int c)
Expand Down
107 changes: 107 additions & 0 deletions premake5.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@

-----------------------------------------------------------------------------------------------------------------------

(function()
-- generate "quickjs-version.h" using VERSION file
local file = io.open("VERSION", "r")
local vers = file:read()
file:close()
vars = vers:gsub("%s+", "")
file = io.open("quickjs-version.h", "w+")
file:write("#define QUICKJS_VERSION \"" .. vers .. "\"\r\n")
file:close()
end)()


workspace "quickjs-msvc"
-- Premake output folder
location(path.join(".build", _ACTION))

platforms { "x86", "x64", "arm32", "arm64" }

-- Configuration settings
configurations { "Debug", "Release" }

filter "platforms:x86"
architecture "x86"
filter "platforms:x64"
architecture "x86_64"
filter "platforms:arm32"
architecture "ARM"
filter "platforms:arm64"
architecture "ARM64"

filter "system:windows"
removeplatforms { "arm32" }

-- Debug configuration
filter { "configurations:Debug" }
defines { "DEBUG" }
symbols "On"
optimize "Off"

-- Release configuration
filter { "configurations:Release" }
defines { "NDEBUG" }
optimize "Speed"
inlining "Auto"

filter { "language:not C#" }
defines { "_CRT_SECURE_NO_WARNINGS" }
buildoptions { "/std:c++latest" }
systemversion "latest"

filter { }
targetdir ".bin/%{cfg.longname}/"
exceptionhandling "Off"
rtti "Off"
--vectorextensions "AVX2"

-----------------------------------------------------------------------------------------------------------------------

project "quickjs"
language "C"
kind "StaticLib"
files {
"cutils.h",
"cutils.c",
"libregexp.c",
"libunicode.c",
"quickjs.c",
"quickjs-libc.c",
"libregexp.h",
"libregexp-opcode.h",
"libunicode.h",
"libunicode-table.h",
"list.h",
"quickjs.h",
"quickjs-atom.h",
"quickjs-libc.h",
"quickjs-opcode.h"
}

-----------------------------------------------------------------------------------------------------------------------

project "qjsc"
language "C"
kind "ConsoleApp"
links { "quickjs" }
files {
"qjsc.c"
}

-----------------------------------------------------------------------------------------------------------------------

project "qjs"
language "C"
kind "ConsoleApp"
links { "quickjs" }
dependson { "qjsc" }
files {
"qjs.c",
"repl.js",
"repl.c"
}

-- Compile repl.js and save bytecode into repl.c
prebuildcommands { "\"%{cfg.buildtarget.directory}/qjsc.exe\" -c -o \"../../repl.c\" -m \"../../repl.js\"" }
8 changes: 6 additions & 2 deletions qjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@
#include <inttypes.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#if defined(__APPLE__)
#include <malloc/malloc.h>
#include <unistd.h>
#elif defined(__linux__)
#include <malloc.h>
#include <unistd.h>
#endif

#include "cutils.h"
#include "quickjs-libc.h"
#include "quickjs-version.h"

extern const uint8_t qjsc_repl[];
extern const uint32_t qjsc_repl_size;
Expand Down Expand Up @@ -276,7 +278,7 @@ static const JSMallocFunctions trace_mf = {

void help(void)
{
printf("QuickJS version " CONFIG_VERSION "\n"
printf("QuickJS version " QUICKJS_VERSION "\n"
"usage: " PROG_NAME " [options] [file [args]]\n"
"-h --help list options\n"
"-e --eval EXPR evaluate EXPR\n"
Expand Down Expand Up @@ -448,8 +450,10 @@ int main(int argc, char **argv)
}
}

#ifdef CONFIG_BIGNUM
if (load_jscalc)
bignum_ext = 1;
#endif

if (trace_memory) {
js_trace_malloc_init(&trace_data);
Expand Down
7 changes: 5 additions & 2 deletions qjsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@
#include <inttypes.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#if !defined(_WIN32)
#include <sys/wait.h>
#include <unistd.h>
#else
#include "win/getopt.h"
#endif

#include "cutils.h"
#include "quickjs-libc.h"
#include "quickjs-version.h"

typedef struct {
char *name;
Expand Down Expand Up @@ -341,7 +344,7 @@ static const char main_c_template2[] =

void help(void)
{
printf("QuickJS Compiler version " CONFIG_VERSION "\n"
printf("QuickJS Compiler version " QUICKJS_VERSION "\n"
"usage: " PROG_NAME " [options] [files]\n"
"\n"
"options are:\n"
Expand Down
Loading

0 comments on commit 4298c1a

Please sign in to comment.