mirror of
https://github.com/luau-lang/luau.git
synced 2024-12-13 21:40:43 +00:00
54324867df
* Support `["prop"]` syntax on class definitions in definition files. (#704) * Improve type checking performance for complex overloaded functions * Fix rare cases of incorrect stack traces for out of memory errors at runtime
154 lines
4.8 KiB
C++
154 lines
4.8 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
|
|
#include "lobject.h"
|
|
|
|
#include "lstate.h"
|
|
#include "lstring.h"
|
|
#include "lgc.h"
|
|
#include "ldo.h"
|
|
#include "lnumutils.h"
|
|
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
const TValue luaO_nilobject_ = {{NULL}, {0}, LUA_TNIL};
|
|
|
|
int luaO_log2(unsigned int x)
|
|
{
|
|
static const uint8_t log_2[256] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
|
|
int l = -1;
|
|
while (x >= 256)
|
|
{
|
|
l += 8;
|
|
x >>= 8;
|
|
}
|
|
return l + log_2[x];
|
|
}
|
|
|
|
int luaO_rawequalObj(const TValue* t1, const TValue* t2)
|
|
{
|
|
if (ttype(t1) != ttype(t2))
|
|
return 0;
|
|
else
|
|
switch (ttype(t1))
|
|
{
|
|
case LUA_TNIL:
|
|
return 1;
|
|
case LUA_TNUMBER:
|
|
return luai_numeq(nvalue(t1), nvalue(t2));
|
|
case LUA_TVECTOR:
|
|
return luai_veceq(vvalue(t1), vvalue(t2));
|
|
case LUA_TBOOLEAN:
|
|
return bvalue(t1) == bvalue(t2); // boolean true must be 1 !!
|
|
case LUA_TLIGHTUSERDATA:
|
|
return pvalue(t1) == pvalue(t2);
|
|
default:
|
|
LUAU_ASSERT(iscollectable(t1));
|
|
return gcvalue(t1) == gcvalue(t2);
|
|
}
|
|
}
|
|
|
|
int luaO_rawequalKey(const TKey* t1, const TValue* t2)
|
|
{
|
|
if (ttype(t1) != ttype(t2))
|
|
return 0;
|
|
else
|
|
switch (ttype(t1))
|
|
{
|
|
case LUA_TNIL:
|
|
return 1;
|
|
case LUA_TNUMBER:
|
|
return luai_numeq(nvalue(t1), nvalue(t2));
|
|
case LUA_TVECTOR:
|
|
return luai_veceq(vvalue(t1), vvalue(t2));
|
|
case LUA_TBOOLEAN:
|
|
return bvalue(t1) == bvalue(t2); // boolean true must be 1 !!
|
|
case LUA_TLIGHTUSERDATA:
|
|
return pvalue(t1) == pvalue(t2);
|
|
default:
|
|
LUAU_ASSERT(iscollectable(t1));
|
|
return gcvalue(t1) == gcvalue(t2);
|
|
}
|
|
}
|
|
|
|
int luaO_str2d(const char* s, double* result)
|
|
{
|
|
char* endptr;
|
|
*result = luai_str2num(s, &endptr);
|
|
if (endptr == s)
|
|
return 0; // conversion failed
|
|
if (*endptr == 'x' || *endptr == 'X') // maybe an hexadecimal constant?
|
|
*result = cast_num(strtoul(s, &endptr, 16));
|
|
if (*endptr == '\0')
|
|
return 1; // most common case
|
|
while (isspace(cast_to(unsigned char, *endptr)))
|
|
endptr++;
|
|
if (*endptr != '\0')
|
|
return 0; // invalid trailing characters?
|
|
return 1;
|
|
}
|
|
|
|
const char* luaO_pushvfstring(lua_State* L, const char* fmt, va_list argp)
|
|
{
|
|
char result[LUA_BUFFERSIZE];
|
|
vsnprintf(result, sizeof(result), fmt, argp);
|
|
|
|
setsvalue(L, L->top, luaS_new(L, result));
|
|
incr_top(L);
|
|
return svalue(L->top - 1);
|
|
}
|
|
|
|
const char* luaO_pushfstring(lua_State* L, const char* fmt, ...)
|
|
{
|
|
const char* msg;
|
|
va_list argp;
|
|
va_start(argp, fmt);
|
|
msg = luaO_pushvfstring(L, fmt, argp);
|
|
va_end(argp);
|
|
return msg;
|
|
}
|
|
|
|
const char* luaO_chunkid(char* buf, size_t buflen, const char* source, size_t srclen)
|
|
{
|
|
if (*source == '=')
|
|
{
|
|
if (srclen <= buflen)
|
|
return source + 1;
|
|
// truncate the part after =
|
|
memcpy(buf, source + 1, buflen - 1);
|
|
buf[buflen - 1] = '\0';
|
|
}
|
|
else if (*source == '@')
|
|
{
|
|
if (srclen <= buflen)
|
|
return source + 1;
|
|
// truncate the part after @
|
|
memcpy(buf, "...", 3);
|
|
memcpy(buf + 3, source + srclen - (buflen - 4), buflen - 4);
|
|
buf[buflen - 1] = '\0';
|
|
}
|
|
else
|
|
{ // buf = [string "string"]
|
|
size_t len = strcspn(source, "\n\r"); // stop at first newline
|
|
buflen -= sizeof("[string \"...\"]");
|
|
if (len > buflen)
|
|
len = buflen;
|
|
strcpy(buf, "[string \"");
|
|
if (source[len] != '\0')
|
|
{ // must truncate?
|
|
strncat(buf, source, len);
|
|
strcat(buf, "...");
|
|
}
|
|
else
|
|
strcat(buf, source);
|
|
strcat(buf, "\"]");
|
|
}
|
|
return buf;
|
|
}
|