luau/VM/src/lobject.cpp
Andy Friesen 54324867df
Sync to upstream/release/550 (#723)
* 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
2022-10-21 10:54:01 -07:00

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;
}