/* * Copyright (C) 2010-2015 Marvell International Ltd. * Copyright (C) 2002-2010 Kinoma, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ void fxBuildJSON(txMachine* the) { txSlot* xs; mxPush(mxGlobal); mxPush(mxObjectPrototype); fxNewObjectInstance(the); fxNewHostFunction(the, fx_JSON_parse, 2); fxQueueID(the, fxID(the, "parse"), XS_DONT_ENUM_FLAG); fxNewHostFunction(the, fx_JSON_stringify, 3); fxQueueID(the, fxID(the, "stringify"), XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "JSON"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); the->stack++; xs = fxGetProperty(the, mxGlobal.value.reference, fxID(the, "xs")); mxPush(*xs); mxPush(mxObjectPrototype); fxNewObjectInstance(the); fxNewHostFunction(the, fx_JSON_parse, 1); fxQueueID(the, fxID(the, "parse"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); fxNewHostFunction(the, fx_JSON_stringify, 1); fxQueueID(the, fxID(the, "serialize"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); fxQueueID(the, fxID(the, "json"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); the->stack++; }
txSlot* fxNewIteratorInstance(txMachine* the, txSlot* iterable) { txSlot* instance; txSlot* result; txSlot* property; instance = fxNewObjectInstance(the); mxPush(mxObjectPrototype); result = fxNewObjectInstance(the); property = fxNextUndefinedProperty(the, result, mxID(_value), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG); property = fxNextBooleanProperty(the, property, 0, mxID(_done), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG); property = fxNextSlotProperty(the, instance, the->stack, mxID(_result), XS_GET_ONLY); property = fxNextSlotProperty(the, property, iterable, mxID(_iterable), XS_GET_ONLY); property = fxNextIntegerProperty(the, property, 0, mxID(_index), XS_GET_ONLY); the->stack++; return instance; }
txSlot* fxNewSymbolInstance(txMachine* the) { txSlot* instance; txSlot* property; instance = fxNewObjectInstance(the); property = fxNextSymbolProperty(the, instance, XS_NO_ID, XS_NO_ID, XS_INTERNAL_FLAG | XS_GET_ONLY); return instance; }
void fxBuildHost(txMachine* the) { txSlot* property; txSlot* slot; fxNewHostAccessorGlobal(the, fx_get_sandbox, C_NULL, fxID(the, "sandbox"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); property = fxLastProperty(the, mxObjectPrototype.value.reference); property = fxNextHostAccessorProperty(the, property, fx_Object_prototype_get_sandbox, C_NULL, fxID(the, "sandbox"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxObjectPrototype); property = fxLastProperty(the, fxNewObjectInstance(the)); property = fxNextHostFunctionProperty(the, property, fx_xs_execute, 1, fxID(the, "execute"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_isInstanceOf, 2, fxID(the, "isInstanceOf"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_newInstanceOf, 1, fxID(the, "newInstanceOf"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_script, 1, fxID(the, "script"), XS_GET_ONLY); #ifdef mxProfile property = fxNextHostFunctionProperty(the, property, fx_xs_isProfiling, 0, fxID(the, "isProfiling"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_getProfilingDirectory, 0, fxID(the, "getProfilingDirectory"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_setProfilingDirectory, 1, fxID(the, "setProfilingDirectory"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_startProfiling, 0, fxID(the, "startProfiling"), XS_GET_ONLY); property = fxNextHostFunctionProperty(the, property, fx_xs_stopProfiling, 0, fxID(the, "stopProfiling"), XS_GET_ONLY); #endif #ifdef mxDebug mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_getAddress, 0, fxID(the, "getAddress"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setAddress, 1, fxID(the, "setAddress"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_getAutomatic, 0, fxID(the, "getAutomatic"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setAutomatic, 1, fxID(the, "setAutomatic"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_getBreakOnException, 0, fxID(the, "getBreakOnException"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setBreakOnException, 1, fxID(the, "setBreakOnException"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_getConnected, 0, fxID(the, "getConnected"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setConnected, 1, fxID(the, "setConnected"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_clearAllBreakpoints, 0, fxID(the, "clearAllBreakpoints"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_clearBreakpoint, 2, fxID(the, "clearBreakpoint"), XS_GET_ONLY); slot = fxNextHostFunctionProperty(the, slot, fx_xs_debug_setBreakpoint, 2, fxID(the, "setBreakpoint"), XS_GET_ONLY); property = fxNextSlotProperty(the, property, the->stack, fxID(the, "debug"), XS_GET_ONLY); the->stack++; #endif slot = fxSetGlobalProperty(the, mxGlobal.value.reference, fxID(the, "xs"), C_NULL); slot->flag = XS_GET_ONLY; slot->kind = the->stack->kind; slot->value = the->stack->value; the->stack++; }
void fxThrowError(txMachine* the, txError theError) { if ((theError <= XS_NO_ERROR) || (XS_ERROR_COUNT <= theError)) theError = XS_UNKNOWN_ERROR; mxPush(mxErrorPrototypes(theError)); fxNewObjectInstance(the); mxException = *(the->stack++); fxJump(the); }
txSlot* fxNewSymbolInstance(txMachine* the) { txSlot* instance; txSlot* property; instance = fxNewObjectInstance(the); instance->flag |= XS_VALUE_FLAG; property = fxNextSymbolProperty(the, instance, XS_NO_ID, XS_NO_ID, XS_GET_ONLY); return instance; }
void fx_URIError(txMachine* the) { if (mxResult->kind == XS_UNDEFINED_KIND) { mxPush(mxURIErrorPrototype); fxNewObjectInstance(the); *mxResult = *(the->stack++); } fx_Error_aux(the); }
void fx_Error(txMachine* the) { if (mxTarget->kind == XS_UNDEFINED_KIND) { mxPush(mxErrorPrototype); fxNewObjectInstance(the); mxPullSlot(mxResult); } fx_Error_aux(the); }
void fxBuildGlobal(txMachine* the) { static const txHostFunctionBuilder gx_global_builders[] = { { fx_decodeURI, 1, _decodeURI }, { fx_decodeURIComponent, 1, _decodeURIComponent }, { fx_encodeURI, 1, _encodeURI }, { fx_encodeURIComponent, 1, _encodeURIComponent }, { fx_escape, 1, _escape }, { fx_eval, 1, _eval }, { fx_trace, 1, _trace }, { fx_unescape, 1, _unescape }, { C_NULL, 0, 0 }, }; const txHostFunctionBuilder* builder; txSlot* slot; fxNewGlobalInstance(the); mxPull(mxGlobal); fxNewInstance(the); mxPull(mxObjectPrototype); mxPush(mxObjectPrototype); fxNewFunctionInstance(the, XS_NO_ID); mxPull(mxFunctionPrototype); for (builder = gx_global_builders; builder->callback; builder++) { fxNewHostFunctionGlobal(the, builder->callback, builder->length, mxID(builder->id), XS_DONT_ENUM_FLAG); the->stack++; } slot = fxSetGlobalProperty(the, mxGlobal.value.reference, mxID(_undefined), C_NULL); slot->flag = XS_GET_ONLY; mxPush(mxObjectPrototype); slot = fxNewObjectInstance(the); slot = fxNextHostFunctionProperty(the, slot, fx_Iterator_iterator, 0, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG); mxPull(mxIteratorPrototype); mxPush(mxIteratorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostFunctionProperty(the, slot, fx_Enumerator_next, 0, mxID(_next), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG); fxNewHostConstructor(the, fx_Enumerator, 0, XS_NO_ID); mxPull(mxEnumeratorFunction); }
txSlot* fxNewDateInstance(txMachine* the) { txSlot* instance; txSlot* property; instance = fxNewObjectInstance(the); instance->flag |= XS_VALUE_FLAG; property = fxNextNumberProperty(the, instance, 0, XS_NO_ID, XS_GET_ONLY); property->kind = XS_DATE_KIND; return instance; }
void fxSerializeJSON(txMachine* the, txJSONSerializer* theSerializer) { txSlot* aSlot; txInteger aFlag; aSlot = fxGetInstance(the, mxThis); theSerializer->offset = 0; theSerializer->size = 1024; theSerializer->buffer = c_malloc(1024); if (!theSerializer->buffer) mxUnknownError("out of memory"); if (mxArgc > 1) { aSlot = mxArgv(1); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsFunction(aSlot)) theSerializer->replacer = mxArgv(1); else if (mxIsArray(aSlot)) mxSyntaxError("not yet implememented"); } } if (mxArgc > 2) { aSlot = mxArgv(2); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsNumber(aSlot) || mxIsString(aSlot)) aSlot = aSlot->next; } if ((aSlot->kind == XS_INTEGER_KIND) || (aSlot->kind == XS_NUMBER_KIND)) { txInteger aCount = fxToInteger(the, aSlot), anIndex; if (aCount < 0) aCount = 0; else if (aCount > 10) aCount = 10; for (anIndex = 0; anIndex < aCount; anIndex++) theSerializer->indent[anIndex] = ' '; } else if (mxIsStringPrimitive(aSlot)) c_strncpy((char *)theSerializer->indent, aSlot->value.string, 10); } theSerializer->stack = the->stack; mxPush(mxObjectPrototype); fxNewObjectInstance(the); aFlag = 0; if (mxArgc > 0) mxPushSlot(mxArgv(0)); else mxPushUndefined(); mxPush(mxEmptyString); fxSerializeJSONProperty(the, theSerializer, &aFlag); the->stack++; }
void fxThrowMessage(txMachine* the, txError theError, txString theMessage) { if ((theError <= XS_NO_ERROR) || (XS_ERROR_COUNT <= theError)) theError = XS_UNKNOWN_ERROR; mxPush(mxErrorPrototypes(theError)); fxNewObjectInstance(the); mxPushStringC(theMessage); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); mxException = *(the->stack++); fxJump(the); }
txSlot* fxNewFunctionInstance(txMachine* the, txID name) { txSlot* instance; txSlot* property; instance = fxNewObjectInstance(the); instance->flag |= XS_VALUE_FLAG; /* CODE */ property = instance->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; property->kind = mxEmptyCode.kind; property->value.code = mxEmptyCode.value.code; /* CLOSURE */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; property->kind = XS_NULL_KIND; /* PROTOTYPE */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG; property->kind = XS_NULL_KIND; /* HOME */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; property->kind = XS_NULL_KIND; /* INFO */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; property->kind = XS_INFO_KIND; property->value.info.length = -1; property->value.info.name = name; #ifdef mxProfile property->value.info.profileID = the->profileID; the->profileID++; #endif /* MODULE */ property = property->next = fxNewSlot(the); property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; if (the->frame && (mxFunction->kind == XS_REFERENCE_KIND) && (mxIsFunction(mxFunction->value.reference))) { txSlot* slot = mxFunctionInstanceModule(mxFunction->value.reference); property->kind = slot->kind; property->value = slot->value; } else property->kind = XS_NULL_KIND; return instance; }
txSlot* fxNewArrayInstance(txMachine* the) { txSlot* instance; txSlot* property; instance = fxNewObjectInstance(the); instance->flag |= XS_VALUE_FLAG; property = instance->next = fxNewSlot(the); property->kind = XS_ARRAY_KIND; property->value.array.length = 0; property->value.array.address = C_NULL; return instance; }
void fxParseJSONObject(txMachine* the, txJSONParser* theParser) { txSlot* anObject; txSlot* at; txSlot* aProperty; fxGetNextJSONToken(the, theParser); mxPush(mxObjectPrototype); anObject = fxNewObjectInstance(the); for (;;) { if (theParser->token == XS_JSON_TOKEN_RIGHT_BRACE) break; if (theParser->token != XS_JSON_TOKEN_STRING) { mxSyntaxError("missing name"); break; } mxPushString(theParser->string->value.string); at = fxAt(the, the->stack); if (theParser->reviver) mxPushString(theParser->string->value.string); fxGetNextJSONToken(the, theParser); if (theParser->token != XS_JSON_TOKEN_COLON) { mxSyntaxError("missing :"); break; } fxGetNextJSONToken(the, theParser); fxParseJSONValue(the, theParser); if (theParser->reviver) { mxPushInteger(2); mxPushReference(anObject); mxPushReference(theParser->reviver); fxCall(the); } if (the->stack->kind != XS_UNDEFINED_KIND) { aProperty = fxSetProperty(the, anObject, at->value.at.id, at->value.at.index, XS_OWN); aProperty->kind = the->stack->kind; aProperty->value = the->stack->value; } the->stack++; the->stack++; if (theParser->token != XS_JSON_TOKEN_COMMA) break; fxGetNextJSONToken(the, theParser); } if (theParser->token != XS_JSON_TOKEN_RIGHT_BRACE) mxSyntaxError("missing }"); fxGetNextJSONToken(the, theParser); }
void fxBuildError(txMachine* the) { txSlot* slot; mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostFunctionProperty(the, slot, fx_Error_toString, 0, mxID(_toLocaleString), XS_DONT_ENUM_FLAG); slot = fxNextHostFunctionProperty(the, slot, fx_Error_toString, 0, mxID(_toString), XS_DONT_ENUM_FLAG); slot = fxNextStringProperty(the, slot, "Error", mxID(_name), XS_DONT_ENUM_FLAG); slot = fxNextStringProperty(the, slot, "", mxID(_message), XS_DONT_ENUM_FLAG); mxErrorPrototype = *the->stack; fxNewHostConstructorGlobal(the, fx_Error, 0, mxID(_Error), XS_GET_ONLY); the->stack++; mxPush(mxErrorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextStringProperty(the, slot, "EvalError", mxID(_name), XS_DONT_ENUM_FLAG); mxEvalErrorPrototype = *the->stack; fxNewHostConstructorGlobal(the, fx_EvalError, 1, mxID(_EvalError), XS_GET_ONLY); the->stack++; mxPush(mxErrorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextStringProperty(the, slot, "RangeError", mxID(_name), XS_DONT_ENUM_FLAG); mxRangeErrorPrototype = *the->stack; fxNewHostConstructorGlobal(the, fx_RangeError, 1, mxID(_RangeError), XS_GET_ONLY); the->stack++; mxPush(mxErrorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextStringProperty(the, slot, "ReferenceError", mxID(_name), XS_DONT_ENUM_FLAG); mxReferenceErrorPrototype = *the->stack; fxNewHostConstructorGlobal(the, fx_ReferenceError, 1, mxID(_ReferenceError), XS_GET_ONLY); the->stack++; mxPush(mxErrorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextStringProperty(the, slot, "SyntaxError", mxID(_name), XS_DONT_ENUM_FLAG); mxSyntaxErrorPrototype = *the->stack; fxNewHostConstructorGlobal(the, fx_SyntaxError, 1, mxID(_SyntaxError), XS_GET_ONLY); the->stack++; mxPush(mxErrorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextStringProperty(the, slot, "TypeError", mxID(_name), XS_DONT_ENUM_FLAG); mxTypeErrorPrototype = *the->stack; fxNewHostConstructorGlobal(the, fx_TypeError, 1, mxID(_TypeError), XS_GET_ONLY); the->stack++; mxPush(mxErrorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextStringProperty(the, slot, "URIError", mxID(_name), XS_DONT_ENUM_FLAG); mxURIErrorPrototype = *the->stack; fxNewHostConstructorGlobal(the, fx_URIError, 1, mxID(_URIError), XS_GET_ONLY); the->stack++; }
void fxBuildJSON(txMachine* the) { static const txHostFunctionBuilder gx_JSON_builders[] = { { fx_JSON_parse, 2, _parse }, { fx_JSON_stringify, 3, _stringify }, { C_NULL, 0, 0 }, }; const txHostFunctionBuilder* builder; txSlot* slot; mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); for (builder = gx_JSON_builders; builder->callback; builder++) slot = fxNextHostFunctionProperty(the, slot, builder->callback, builder->length, mxID(builder->id), XS_DONT_ENUM_FLAG); slot = fxNextStringXProperty(the, slot, "JSON", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxSetGlobalProperty(the, mxGlobal.value.reference, mxID(_JSON)); slot->flag = XS_DONT_ENUM_FLAG; slot->kind = the->stack->kind; slot->value = the->stack->value; the->stack++; }
void fxParseJSONObject(txScriptParser* theParser) { txMachine* the = theParser->the; txSlot* anObject; txSlot* aProperty; txID anID; fxGetNextJSONToken(theParser); *(--the->stack) = mxObjectPrototype; anObject = fxNewObjectInstance(the); for (;;) { if (theParser->token == XS_TOKEN_RIGHT_BRACE) break; if (theParser->token != XS_TOKEN_STRING) { fxReportParserError(theParser, "missing name"); break; } mxInitSlot(--the->stack, XS_STRING_KIND); the->stack->value.string = theParser->string->value.string; fxGetNextJSONToken(theParser); if (theParser->token != XS_TOKEN_COLON) { fxReportParserError(theParser, "missing :"); break; } fxGetNextJSONToken(theParser); fxParseJSONValue(theParser); aProperty = fxSetPropertyAt(the, anObject, the->stack + 1, &anID, C_NULL); aProperty->kind = the->stack->kind; aProperty->value = the->stack->value; the->stack += 2; if (theParser->token != XS_TOKEN_COMMA) break; fxGetNextJSONToken(theParser); } if (theParser->token != XS_TOKEN_RIGHT_BRACE) fxReportParserError(theParser, "missing }"); fxGetNextJSONToken(theParser); }
void fxNewInstanceOf(txMachine* the) { txSlot* aParent; if (the->stack->kind == XS_NULL_KIND) { txSlot* instance = fxNewSlot(the); instance->kind = XS_INSTANCE_KIND; instance->value.instance.garbage = C_NULL; instance->value.instance.prototype = C_NULL; the->stack->value.reference = instance; the->stack->kind = XS_REFERENCE_KIND; } else { fxToInstance(the, the->stack); aParent = fxGetInstance(the, the->stack); if (aParent->flag & XS_VALUE_FLAG) { switch (aParent->next->kind) { case XS_CALLBACK_KIND: case XS_CODE_KIND: fxNewFunctionInstance(the, XS_NO_ID); break; case XS_ARRAY_KIND: fxNewArrayInstance(the); break; case XS_STRING_KIND: case XS_STRING_X_KIND: fxNewStringInstance(the); break; case XS_BOOLEAN_KIND: fxNewBooleanInstance(the); break; case XS_NUMBER_KIND: fxNewNumberInstance(the); break; case XS_DATE_KIND: fxNewDateInstance(the); break; case XS_REGEXP_KIND: fxNewRegExpInstance(the); break; case XS_SYMBOL_KIND: fxNewSymbolInstance(the); break; case XS_HOST_KIND: fxNewHostInstance(the); break; case XS_PROMISE_KIND: fxNewPromiseInstance(the); break; case XS_PROXY_KIND: fxNewProxyInstance(the); break; case XS_MAP_KIND: fxNewMapInstance(the); break; case XS_SET_KIND: fxNewSetInstance(the); break; case XS_WEAK_MAP_KIND: fxNewWeakMapInstance(the); break; case XS_WEAK_SET_KIND: fxNewWeakSetInstance(the); break; case XS_ARRAY_BUFFER_KIND: fxNewArrayBufferInstance(the); break; case XS_DATA_VIEW_KIND: fxNewDataViewInstance(the); break; case XS_TYPED_ARRAY_KIND: fxNewTypedArrayInstance(the, aParent->next->value.typedArray); break; case XS_STACK_KIND: fxNewGeneratorInstance(the); break; default: mxSyntaxError("C: xsNewInstanceOf: invalid prototype"); break; } } else fxNewObjectInstance(the); } }
void fx_JSON_stringify(txMachine* the) { txSlot* aSlot; volatile txJSONSerializer aSerializer; txFlag aFlag; mxTry(the) { aSlot = fxGetInstance(the, mxThis); if (aSlot->flag & XS_SANDBOX_FLAG) the->frame->flag |= XS_SANDBOX_FLAG; else the->frame->flag |= the->frame->next->flag & XS_SANDBOX_FLAG; c_memset((txJSONSerializer*)&aSerializer, 0, sizeof(aSerializer)); aSerializer.offset = 0; aSerializer.size = 1024; aSerializer.buffer = c_malloc(1024); if (!aSerializer.buffer) fxThrowError(the, XS_RANGE_ERROR); if (mxArgc > 1) { aSlot = mxArgv(1); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsFunction(aSlot)) aSerializer.replacer = mxArgv(1); else if (mxIsArray(aSlot)) mxDebug0(the, XS_SYNTAX_ERROR, "not yet implememented"); } } if (mxArgc > 2) { aSlot = mxArgv(2); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsNumber(aSlot) || mxIsString(aSlot)) aSlot = aSlot->next; } if ((aSlot->kind == XS_INTEGER_KIND) || (aSlot->kind == XS_NUMBER_KIND)) { txInteger aCount = fxToInteger(the, aSlot), anIndex; if (aCount < 0) aCount = 0; else if (aCount > 10) aCount = 10; for (anIndex = 0; anIndex < aCount; anIndex++) aSerializer.indent[anIndex] = ' '; } else if (aSlot->kind == XS_STRING_KIND) c_strncpy((char *)aSerializer.indent, aSlot->value.string, 10); } aSerializer.stack = the->stack; *(--the->stack) = mxObjectPrototype; fxNewObjectInstance(the); aFlag = 0; if (mxArgc > 0) *(--the->stack) = *mxArgv(0); else mxZeroSlot(--the->stack); *(--the->stack) = mxEmptyString; fxSerializeJSONProperty(the, (txJSONSerializer*)&aSerializer, &aFlag); the->stack++; if (aSerializer.offset) { mxResult->value.string = (txString)fxNewChunk(the, aSerializer.offset + 1); c_memcpy(mxResult->value.string, aSerializer.buffer, aSerializer.offset); mxResult->value.string[aSerializer.offset] = 0; mxResult->kind = XS_STRING_KIND; } c_free(aSerializer.buffer); } mxCatch(the) { if (aSerializer.buffer) c_free(aSerializer.buffer); fxJump(the); } }
void fxBuildError(txMachine* the) { mxPush(mxGlobal); mxPush(mxObjectPrototype); fxNewObjectInstance(the); mxPushStringC("Error"); fxQueueID(the, fxID(the, "name"), XS_DONT_ENUM_FLAG); mxPush(mxEmptyString); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); fxNewHostFunction(the, fx_Error_toString, 0); fxQueueID(the, fxID(the, "toLocaleString"), XS_DONT_ENUM_FLAG); fxNewHostFunction(the, fx_Error_toString, 0); fxQueueID(the, fxID(the, "toString"), XS_DONT_ENUM_FLAG); fxAliasInstance(the, the->stack); mxErrorPrototype = *the->stack; fxNewHostConstructor(the, fx_Error, 1); the->stack->value.reference->next->next->next->flag |= XS_DONT_SET_FLAG; *(--the->stack) = mxErrorPrototype; fxPutID(the, fxID(the, "constructor"), XS_DONT_ENUM_FLAG, XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "Error"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxErrorPrototype); fxNewObjectInstance(the); mxPushStringC("EvalError"); fxQueueID(the, fxID(the, "name"), XS_DONT_ENUM_FLAG); mxPush(mxEmptyString); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); fxAliasInstance(the, the->stack); mxEvalErrorPrototype = *the->stack; fxNewHostConstructor(the, fx_EvalError, 1); the->stack->value.reference->next->next->next->flag |= XS_DONT_SET_FLAG; *(--the->stack) = mxEvalErrorPrototype; fxPutID(the, fxID(the, "constructor"), XS_DONT_ENUM_FLAG, XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "EvalError"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxErrorPrototype); fxNewObjectInstance(the); mxPushStringC("RangeError"); fxQueueID(the, fxID(the, "name"), XS_DONT_ENUM_FLAG); mxPush(mxEmptyString); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); fxAliasInstance(the, the->stack); mxRangeErrorPrototype = *the->stack; fxNewHostConstructor(the, fx_RangeError, 1); the->stack->value.reference->next->next->next->flag |= XS_DONT_SET_FLAG; *(--the->stack) = mxRangeErrorPrototype; fxPutID(the, fxID(the, "constructor"), XS_DONT_ENUM_FLAG, XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "RangeError"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxErrorPrototype); fxNewObjectInstance(the); mxPushStringC("ReferenceError"); fxQueueID(the, fxID(the, "name"), XS_DONT_ENUM_FLAG); mxPush(mxEmptyString); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); fxAliasInstance(the, the->stack); mxReferenceErrorPrototype = *the->stack; fxNewHostConstructor(the, fx_ReferenceError, 1); the->stack->value.reference->next->next->next->flag |= XS_DONT_SET_FLAG; *(--the->stack) = mxReferenceErrorPrototype; fxPutID(the, fxID(the, "constructor"), XS_DONT_ENUM_FLAG, XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "ReferenceError"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxErrorPrototype); fxNewObjectInstance(the); mxPushStringC("SyntaxError"); fxQueueID(the, fxID(the, "name"), XS_DONT_ENUM_FLAG); mxPush(mxEmptyString); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); fxAliasInstance(the, the->stack); mxSyntaxErrorPrototype = *the->stack; fxNewHostConstructor(the, fx_SyntaxError, 1); the->stack->value.reference->next->next->next->flag |= XS_DONT_SET_FLAG; *(--the->stack) = mxSyntaxErrorPrototype; fxPutID(the, fxID(the, "constructor"), XS_DONT_ENUM_FLAG, XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "SyntaxError"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxErrorPrototype); fxNewObjectInstance(the); mxPushStringC("TypeError"); fxQueueID(the, fxID(the, "name"), XS_DONT_ENUM_FLAG); mxPush(mxEmptyString); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); fxAliasInstance(the, the->stack); mxTypeErrorPrototype = *the->stack; fxNewHostConstructor(the, fx_TypeError, 1); the->stack->value.reference->next->next->next->flag |= XS_DONT_SET_FLAG; *(--the->stack) = mxTypeErrorPrototype; fxPutID(the, fxID(the, "constructor"), XS_DONT_ENUM_FLAG, XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "TypeError"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxErrorPrototype); fxNewObjectInstance(the); mxPushStringC("URIError"); fxQueueID(the, fxID(the, "name"), XS_DONT_ENUM_FLAG); mxPush(mxEmptyString); fxQueueID(the, fxID(the, "message"), XS_DONT_ENUM_FLAG); fxAliasInstance(the, the->stack); mxURIErrorPrototype = *the->stack; fxNewHostConstructor(the, fx_URIError, 1); the->stack->value.reference->next->next->next->flag |= XS_DONT_SET_FLAG; *(--the->stack) = mxURIErrorPrototype; fxPutID(the, fxID(the, "constructor"), XS_DONT_ENUM_FLAG, XS_DONT_ENUM_FLAG); fxQueueID(the, fxID(the, "URIError"), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); the->stack++; }
txSlot* fxNewArgumentsInstance(txMachine* the) { txSlot* anInstance; txSlot* aProperty; txID aCount, anID; txSlot* aFunction; txSlot* aSlot; mxPush(mxObjectPrototype); anInstance = fxNewObjectInstance(the); the->stack->ID = the->argumentsID; the->stack->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty = anInstance->next = fxNewSlot(the); aProperty->flag = XS_DONT_ENUM_FLAG; aProperty->ID = the->lengthID; aProperty->kind = XS_INTEGER_KIND; aProperty->value.integer = mxArgc; aCount = (txID)(aProperty->value.integer); if (the->frame->flag & XS_STRICT_FLAG) { aFunction = mxThrowTypeErrorFunction.value.reference; aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG; aProperty->ID = the->calleeID; aProperty->kind = XS_ACCESSOR_KIND; aProperty->value.accessor.getter = aFunction; aProperty->value.accessor.setter = aFunction; aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG; aProperty->ID = the->callerID; aProperty->kind = XS_ACCESSOR_KIND; aProperty->value.accessor.getter = aFunction; aProperty->value.accessor.setter = aFunction; for (anID = 0; anID < aCount; anID++) { aSlot = the->frame + 4 + aCount - anID; aProperty = aProperty->next = fxNewSlot(the); aProperty->ID = anID; aProperty->kind = aSlot->kind; aProperty->value = aSlot->value; } } else { aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_ENUM_FLAG; aProperty->ID = the->calleeID; aProperty->kind = mxFunction->kind; aProperty->value = mxFunction->value; aProperty = aProperty->next = fxNewSlot(the); aProperty->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG; aProperty->ID = the->callerID; aProperty->kind = XS_NULL_KIND; aProperty->value.array.length = aCount; aProperty->value.array.address = the->frame; for (anID = 0; anID < aCount; anID++) { aProperty = aProperty->next = fxNewSlot(the); aProperty->ID = anID; aProperty->kind = XS_ACCESSOR_KIND; aProperty->value.accessor.getter = mxGetArgumentFunction.value.reference; aProperty->value.accessor.setter = mxSetArgumentFunction.value.reference; } } return anInstance; }
void fxBuildArray(txMachine* the) { static const txHostFunctionBuilder gx_Array_prototype_builders[] = { { fx_Array_prototype_concat, 1, _concat }, { fx_Array_prototype_copyWithin, 2, _copyWithin }, { fx_Array_prototype_entries, 0, _entries }, { fx_Array_prototype_every, 1, _every }, { fx_Array_prototype_fill, 1, _fill }, { fx_Array_prototype_filter, 1, _filter }, { fx_Array_prototype_find, 1, _find }, { fx_Array_prototype_findIndex, 1, _findIndex }, { fx_Array_prototype_forEach, 1, _forEach }, { fx_Array_prototype_indexOf, 1, _indexOf }, { fx_Array_prototype_join, 1, _join }, { fx_Array_prototype_keys, 0, _keys }, { fx_Array_prototype_lastIndexOf, 1, _lastIndexOf }, { fx_Array_prototype_map, 1, _map }, { fx_Array_prototype_pop, 0, _pop }, { fx_Array_prototype_push, 1, _push }, { fx_Array_prototype_reduce, 1, _reduce }, { fx_Array_prototype_reduceRight, 1, _reduceRight }, { fx_Array_prototype_reverse, 0, _reverse }, { fx_Array_prototype_shift, 0, _shift }, { fx_Array_prototype_slice, 2, _slice }, { fx_Array_prototype_some, 1, _some }, { fx_Array_prototype_sort, 1, _sort }, { fx_Array_prototype_splice, 2, _splice }, { fx_Array_prototype_join, 0, _toString }, { fx_Array_prototype_join, 0, _toLocaleString }, { fx_Array_prototype_unshift, 1, _unshift }, { fx_Array_prototype_values, 0, _values }, { fx_Array_prototype_values, 0, _Symbol_iterator }, { C_NULL, 0, 0 }, }; static const txHostFunctionBuilder gx_Array_builders[] = { { fx_Array_from, 1, _from }, { fx_Array_isArray, 1, _isArray }, { fx_Array_of, 1, _of }, { C_NULL, 0, 0 }, }; const txHostFunctionBuilder* builder; txSlot* slot; txSlot* unscopable; mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewArrayInstance(the)); slot = fxNextHostAccessorProperty(the, slot, fx_Array_prototype_length_get, fx_Array_prototype_length_set, mxID(_length), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG); for (builder = gx_Array_prototype_builders; builder->callback; builder++) slot = fxNextHostFunctionProperty(the, slot, builder->callback, builder->length, mxID(builder->id), XS_DONT_ENUM_FLAG); slot = fxNextBooleanProperty(the, slot, 1, mxID(_Symbol_isConcatSpreadable), XS_DONT_ENUM_FLAG); slot = fxNextStringProperty(the, slot, "Array", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPush(mxObjectPrototype); unscopable = fxLastProperty(the, fxNewObjectInstance(the)); unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_find), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_findIndex), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_fill), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_copyWithin), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_entries), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_keys), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_values), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextSlotProperty(the, slot, the->stack++, mxID(_Symbol_unscopables), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxArrayPrototype = *the->stack; slot = fxLastProperty(the, fxNewHostConstructorGlobal(the, fx_Array, 1, mxID(_Array), XS_GET_ONLY)); for (builder = gx_Array_builders; builder->callback; builder++) slot = fxNextHostFunctionProperty(the, slot, builder->callback, builder->length, mxID(builder->id), XS_DONT_ENUM_FLAG); slot = fxNextHostAccessorProperty(the, slot, fx_species_get, C_NULL, mxID(_Symbol_species), XS_DONT_ENUM_FLAG); the->stack++; mxPush(mxIteratorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostFunctionProperty(the, slot, fx_Array_prototype_entries_next, 0, mxID(_next), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG); slot = fxNextStringProperty(the, slot, "Array Iterator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPull(mxArrayEntriesIteratorPrototype); mxPush(mxIteratorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostFunctionProperty(the, slot, fx_Array_prototype_keys_next, 0, mxID(_next), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG); slot = fxNextStringProperty(the, slot, "Array Iterator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPull(mxArrayKeysIteratorPrototype); mxPush(mxIteratorPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostFunctionProperty(the, slot, fx_Array_prototype_values_next, 0, mxID(_next), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG); slot = fxNextStringProperty(the, slot, "Array Iterator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxPull(mxArrayValuesIteratorPrototype); mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextStringProperty(the, slot, "Arguments", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxParametersPrototype = *the->stack; the->stack++; mxPush(mxObjectPrototype); slot = fxLastProperty(the, fxNewObjectInstance(the)); slot = fxNextHostAccessorProperty(the, slot, fx_Arguments_prototype_callee, fx_Arguments_prototype_callee, mxID(_callee), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextHostAccessorProperty(the, slot, fx_Arguments_prototype_caller, fx_Arguments_prototype_caller, mxID(_caller), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); slot = fxNextHostFunctionProperty(the, slot, fx_Array_prototype_values, 0, mxID(_Symbol_iterator), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG); slot = fxNextStringProperty(the, slot, "Arguments", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG); mxArgumentsStrictPrototype = *the->stack; the->stack++; }