2021-08-05 21:43:53 +00:00
|
|
|
/*
|
|
|
|
* QuickJS Javascript Engine
|
|
|
|
*
|
|
|
|
* Copyright (c) 2017-2021 Fabrice Bellard
|
|
|
|
* Copyright (c) 2017-2021 Charlie Gordon
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
* THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
#include "third_party/quickjs/internal.h"
|
|
|
|
#include "third_party/quickjs/libregexp.h"
|
|
|
|
#include "third_party/quickjs/quickjs.h"
|
|
|
|
|
|
|
|
asm(".ident\t\"\\n\\n\
|
|
|
|
QuickJS (MIT License)\\n\
|
|
|
|
Copyright (c) 2017-2021 Fabrice Bellard\\n\
|
|
|
|
Copyright (c) 2017-2021 Charlie Gordon\"");
|
|
|
|
asm(".include \"libc/disclaimer.inc\"");
|
|
|
|
/* clang-format off */
|
|
|
|
|
|
|
|
JSValue JS_ThrowTypeErrorRevokedProxy(JSContext *ctx)
|
|
|
|
{
|
|
|
|
return JS_ThrowTypeError(ctx, "revoked proxy");
|
|
|
|
}
|
|
|
|
|
|
|
|
JSValue JS_ThrowTypeErrorInvalidClass(JSContext *ctx, int class_id)
|
|
|
|
{
|
|
|
|
JSRuntime *rt = ctx->rt;
|
|
|
|
JSAtom name;
|
|
|
|
name = rt->class_array[class_id].class_name;
|
|
|
|
return JS_ThrowTypeErrorAtom(ctx, "%s object expected", name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* warning: the refcount of the context is not incremented. Return
|
|
|
|
NULL in case of exception (case of revoked proxy only) */
|
|
|
|
JSContext *JS_GetFunctionRealm(JSContext *ctx, JSValueConst func_obj)
|
|
|
|
{
|
|
|
|
JSObject *p;
|
|
|
|
JSContext *realm;
|
2022-07-22 04:46:07 +00:00
|
|
|
|
2021-08-05 21:43:53 +00:00
|
|
|
if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT)
|
|
|
|
return ctx;
|
|
|
|
p = JS_VALUE_GET_OBJ(func_obj);
|
|
|
|
switch(p->class_id) {
|
|
|
|
case JS_CLASS_C_FUNCTION:
|
|
|
|
realm = p->u.cfunc.realm;
|
|
|
|
break;
|
|
|
|
case JS_CLASS_BYTECODE_FUNCTION:
|
|
|
|
case JS_CLASS_GENERATOR_FUNCTION:
|
|
|
|
case JS_CLASS_ASYNC_FUNCTION:
|
|
|
|
case JS_CLASS_ASYNC_GENERATOR_FUNCTION:
|
|
|
|
{
|
|
|
|
JSFunctionBytecode *b;
|
|
|
|
b = p->u.func.function_bytecode;
|
|
|
|
realm = b->realm;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JS_CLASS_PROXY:
|
|
|
|
{
|
|
|
|
JSProxyData *s = p->u.opaque;
|
|
|
|
if (!s)
|
|
|
|
return ctx;
|
|
|
|
if (s->is_revoked) {
|
|
|
|
JS_ThrowTypeErrorRevokedProxy(ctx);
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
realm = JS_GetFunctionRealm(ctx, s->target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case JS_CLASS_BOUND_FUNCTION:
|
|
|
|
{
|
|
|
|
JSBoundFunction *bf = p->u.bound_function;
|
|
|
|
realm = JS_GetFunctionRealm(ctx, bf->func_obj);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
realm = ctx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return realm;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSValue js_create_from_ctor(JSContext *ctx, JSValueConst ctor,
|
|
|
|
int class_id)
|
|
|
|
{
|
|
|
|
JSValue proto, obj;
|
|
|
|
JSContext *realm;
|
2022-07-22 04:46:07 +00:00
|
|
|
|
2021-08-05 21:43:53 +00:00
|
|
|
if (JS_IsUndefined(ctor)) {
|
|
|
|
proto = JS_DupValue(ctx, ctx->class_proto[class_id]);
|
|
|
|
} else {
|
|
|
|
proto = JS_GetProperty(ctx, ctor, JS_ATOM_prototype);
|
|
|
|
if (JS_IsException(proto))
|
|
|
|
return proto;
|
|
|
|
if (!JS_IsObject(proto)) {
|
|
|
|
JS_FreeValue(ctx, proto);
|
|
|
|
realm = JS_GetFunctionRealm(ctx, ctor);
|
|
|
|
if (!realm)
|
|
|
|
return JS_EXCEPTION;
|
|
|
|
proto = JS_DupValue(ctx, realm->class_proto[class_id]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
obj = JS_NewObjectProtoClass(ctx, proto, class_id);
|
|
|
|
JS_FreeValue(ctx, proto);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
int JS_ToBoolFree(JSContext *ctx, JSValue val)
|
|
|
|
{
|
|
|
|
uint32_t tag = JS_VALUE_GET_TAG(val);
|
|
|
|
switch(tag) {
|
|
|
|
case JS_TAG_INT:
|
|
|
|
return JS_VALUE_GET_INT(val) != 0;
|
|
|
|
case JS_TAG_BOOL:
|
|
|
|
case JS_TAG_NULL:
|
|
|
|
case JS_TAG_UNDEFINED:
|
|
|
|
return JS_VALUE_GET_INT(val);
|
|
|
|
case JS_TAG_EXCEPTION:
|
|
|
|
return -1;
|
|
|
|
case JS_TAG_STRING:
|
|
|
|
{
|
|
|
|
BOOL ret = JS_VALUE_GET_STRING(val)->len != 0;
|
|
|
|
JS_FreeValue(ctx, val);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#ifdef CONFIG_BIGNUM
|
|
|
|
case JS_TAG_BIG_INT:
|
|
|
|
case JS_TAG_BIG_FLOAT:
|
|
|
|
{
|
|
|
|
JSBigFloat *p = JS_VALUE_GET_PTR(val);
|
|
|
|
BOOL ret;
|
|
|
|
ret = p->num.expn != BF_EXP_ZERO && p->num.expn != BF_EXP_NAN;
|
|
|
|
JS_FreeValue(ctx, val);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
case JS_TAG_BIG_DECIMAL:
|
|
|
|
{
|
|
|
|
JSBigDecimal *p = JS_VALUE_GET_PTR(val);
|
|
|
|
BOOL ret;
|
|
|
|
ret = p->num.expn != BF_EXP_ZERO && p->num.expn != BF_EXP_NAN;
|
|
|
|
JS_FreeValue(ctx, val);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
case JS_TAG_OBJECT:
|
|
|
|
{
|
|
|
|
JSObject *p = JS_VALUE_GET_OBJ(val);
|
|
|
|
BOOL ret;
|
|
|
|
ret = !p->is_HTMLDDA;
|
|
|
|
JS_FreeValue(ctx, val);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (JS_TAG_IS_FLOAT64(tag)) {
|
|
|
|
double d = JS_VALUE_GET_FLOAT64(val);
|
|
|
|
return !isnan(d) && d != 0;
|
|
|
|
} else {
|
|
|
|
JS_FreeValue(ctx, val);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int JS_ToBool(JSContext *ctx, JSValueConst val)
|
|
|
|
{
|
|
|
|
return JS_ToBoolFree(ctx, JS_DupValue(ctx, val));
|
|
|
|
}
|
|
|
|
|
|
|
|
JSValue js_get_this(JSContext *ctx, JSValueConst this_val)
|
|
|
|
{
|
|
|
|
return JS_DupValue(ctx, this_val);
|
|
|
|
}
|