Coverage Report

Created: 2025-06-13 06:10

/src/moddable/xs/sources/xsArguments.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2016-2017  Moddable Tech, Inc.
3
 *
4
 *   This file is part of the Moddable SDK Runtime.
5
 *
6
 *   The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
 *   it under the terms of the GNU Lesser General Public License as published by
8
 *   the Free Software Foundation, either version 3 of the License, or
9
 *   (at your option) any later version.
10
 *
11
 *   The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *   GNU Lesser General Public License for more details.
15
 *
16
 *   You should have received a copy of the GNU Lesser General Public License
17
 *   along with the Moddable SDK Runtime.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * This file incorporates work covered by the following copyright and
20
 * permission notice:
21
 *
22
 *       Copyright (C) 2010-2016 Marvell International Ltd.
23
 *       Copyright (C) 2002-2010 Kinoma, Inc.
24
 *
25
 *       Licensed under the Apache License, Version 2.0 (the "License");
26
 *       you may not use this file except in compliance with the License.
27
 *       You may obtain a copy of the License at
28
 *
29
 *        http://www.apache.org/licenses/LICENSE-2.0
30
 *
31
 *       Unless required by applicable law or agreed to in writing, software
32
 *       distributed under the License is distributed on an "AS IS" BASIS,
33
 *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
 *       See the License for the specific language governing permissions and
35
 *       limitations under the License.
36
 */
37
38
#include "xsAll.h"
39
40
static txBoolean fxArgumentsSloppyDefineOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* descriptor, txFlag mask);
41
static txBoolean fxArgumentsSloppyDeleteProperty(txMachine* the, txSlot* instance, txID id, txIndex index);
42
static txSlot* fxArgumentsSloppyGetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag);
43
static txSlot* fxArgumentsSloppySetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag);
44
45
const txBehavior ICACHE_FLASH_ATTR gxArgumentsSloppyBehavior = {
46
  fxArgumentsSloppyGetProperty,
47
  fxArgumentsSloppySetProperty,
48
  fxOrdinaryCall,
49
  fxOrdinaryConstruct,
50
  fxArgumentsSloppyDefineOwnProperty,
51
  fxArgumentsSloppyDeleteProperty,
52
  fxOrdinaryGetOwnProperty,
53
  fxOrdinaryGetPropertyValue,
54
  fxOrdinaryGetPrototype,
55
  fxOrdinaryHasProperty,
56
  fxOrdinaryIsExtensible,
57
  fxOrdinaryOwnKeys,
58
  fxOrdinaryPreventExtensions,
59
  fxOrdinarySetPropertyValue,
60
  fxOrdinarySetPrototype,
61
};
62
63
void fxBuildArguments(txMachine* the)
64
6.57k
{
65
6.57k
  mxPush(mxObjectPrototype);
66
6.57k
  mxArgumentsSloppyPrototype = *the->stack;
67
6.57k
  mxPop();
68
  
69
6.57k
  mxPush(mxObjectPrototype);
70
6.57k
  mxArgumentsStrictPrototype = *the->stack;
71
6.57k
  mxPop();
72
6.57k
}
73
74
txSlot* fxNewArgumentsSloppyInstance(txMachine* the, txIndex count)
75
0
{
76
0
  txSlot* environment = mxFrameToEnvironment(the->frame);
77
0
  txSlot* instance;
78
0
  txSlot* array;
79
0
  txSlot* property;
80
0
  txIndex index;
81
0
  txSlot* address;
82
0
  txIndex length = (txIndex)mxArgc;
83
0
  instance = fxNewObjectInstance(the);
84
0
  instance->flag |= XS_EXOTIC_FLAG;
85
0
  array = instance->next = fxNewSlot(the);
86
0
  array->flag = XS_INTERNAL_FLAG;
87
0
  array->ID = XS_ARGUMENTS_SLOPPY_BEHAVIOR;
88
0
  array->kind = XS_ARRAY_KIND;
89
0
  array->value.array.length = 0;
90
0
  array->value.array.address = C_NULL;
91
0
  property = fxNextNumberProperty(the, array, length, mxID(_length), XS_DONT_ENUM_FLAG);
92
0
  property = fxNextSlotProperty(the, property, mxFunction, mxID(_callee), XS_DONT_ENUM_FLAG);
93
0
  property = fxNextSlotProperty(the, property, &mxArrayIteratorFunction, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
94
0
  fxSetIndexSize(the, array, length, XS_CHUNK);
95
0
  index = 0;
96
0
  address = array->value.array.address;
97
0
  property = the->scope + count;
98
0
  while ((index < length) && (index < count)) {
99
0
    *((txIndex*)address) = index;
100
0
    address->ID = XS_NO_ID;
101
0
    if ((property < environment) && (property->kind == XS_CLOSURE_KIND)) {
102
0
      address->kind = property->kind;
103
0
      address->value = property->value;
104
0
    }
105
0
    else {
106
0
      txSlot* argument = mxArgv(index);
107
0
      address->kind = argument->kind;
108
0
      address->value = argument->value;
109
0
    }
110
0
    index++;
111
0
    address++;
112
0
    property--;
113
0
  }
114
0
  while (index < length) {
115
0
    property = mxArgv(index);
116
0
    *((txIndex*)address) = index;
117
0
    address->ID = XS_NO_ID;
118
0
    address->kind = property->kind;
119
0
    address->value = property->value;
120
0
    index++;
121
0
    address++;
122
0
  }
123
0
  return instance;
124
0
}
125
126
txBoolean fxArgumentsSloppyDefineOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* descriptor, txFlag mask) 
127
0
{
128
0
  if (!id) {
129
0
    txSlot* property = fxGetIndexProperty(the, instance->next, index);
130
0
    if (property && (property->kind == XS_CLOSURE_KIND)) {
131
0
      txSlot* closure = property->value.closure;
132
0
      if (mask & XS_ACCESSOR_FLAG) {
133
0
        property->flag = closure->flag;
134
0
        property->kind = closure->kind;
135
0
        property->value = closure->value;
136
0
      }
137
0
      else if ((descriptor->flag & XS_DONT_SET_FLAG) && (mask & XS_DONT_SET_FLAG)) {
138
0
        property->flag = closure->flag;
139
0
        property->kind = closure->kind;
140
0
        property->value = closure->value;
141
0
        if (descriptor->kind != XS_UNINITIALIZED_KIND) {
142
0
          closure->kind = descriptor->kind;
143
0
          closure->value = descriptor->value;
144
0
        }
145
0
      }
146
0
    }
147
0
  }
148
0
  return fxOrdinaryDefineOwnProperty(the, instance, id, index, descriptor, mask);
149
0
}
150
151
txBoolean fxArgumentsSloppyDeleteProperty(txMachine* the, txSlot* instance, txID id, txIndex index)
152
0
{
153
0
  if (!id) {
154
0
    txSlot* property = fxGetIndexProperty(the, instance->next, index);
155
0
    if (property && (property->kind == XS_CLOSURE_KIND)) {
156
0
      if (property->value.closure->flag & XS_DONT_DELETE_FLAG)
157
0
        return 0;
158
0
    }
159
0
  }
160
0
  return fxOrdinaryDeleteProperty(the, instance, id, index);
161
0
}
162
163
txSlot* fxArgumentsSloppyGetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag)
164
0
{
165
0
  txSlot* result = fxOrdinaryGetProperty(the, instance, id, index, flag);
166
0
  if (!id && result && result->kind == XS_CLOSURE_KIND)
167
0
    result = result->value.closure;
168
0
  return result;
169
0
}
170
171
txSlot* fxArgumentsSloppySetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag)
172
0
{
173
0
  txSlot* result = fxOrdinarySetProperty(the, instance, id, index, flag);
174
0
  if (!id && result && result->kind == XS_CLOSURE_KIND)
175
0
    result = result->value.closure;
176
0
  return result;
177
0
}
178
179
txSlot* fxNewArgumentsStrictInstance(txMachine* the, txIndex count)
180
0
{
181
0
  txSlot* instance;
182
0
  txSlot* array;
183
0
  txSlot* property;
184
0
  txSlot* function;
185
0
  txIndex index;
186
0
  txSlot* address;
187
0
  txIndex length = (txIndex)mxArgc;
188
0
  instance = fxNewObjectInstance(the);
189
0
  instance->flag |= XS_EXOTIC_FLAG;
190
0
  array = instance->next = fxNewSlot(the);
191
0
  array->flag = XS_INTERNAL_FLAG;
192
0
  array->ID = XS_ARGUMENTS_STRICT_BEHAVIOR;
193
0
  array->kind = XS_ARRAY_KIND;
194
0
  array->value.array.length = 0;
195
0
  array->value.array.address = C_NULL;
196
0
  property = fxNextNumberProperty(the, array, length, mxID(_length), XS_DONT_ENUM_FLAG);
197
0
  property = fxNextSlotProperty(the, property, &mxArrayIteratorFunction, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
198
0
  function = mxThrowTypeErrorFunction.value.reference;
199
0
  property = property->next = fxNewSlot(the);
200
0
  property->flag = XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG;
201
0
  property->ID = mxID(_callee);
202
0
  property->kind = XS_ACCESSOR_KIND;
203
0
  property->value.accessor.getter = function;
204
0
  property->value.accessor.setter = function;
205
0
  fxSetIndexSize(the, array, length, XS_CHUNK);
206
0
  index = 0;
207
0
  address = array->value.array.address;
208
0
  while (index < length) {
209
0
    property = mxArgv(index);
210
0
    *((txIndex*)address) = index;
211
0
    address->ID = XS_NO_ID;
212
0
    address->kind = property->kind;
213
0
    address->value = property->value;
214
0
    index++;
215
0
    address++;
216
0
  }
217
0
  return instance;
218
0
}
219
220
void fxThrowTypeError(txMachine* the)
221
0
{
222
0
  if (mxFunction->value.reference->flag & XS_CAN_CONSTRUCT_FLAG)
223
0
    mxTypeError("secure mode");
224
0
  mxTypeError("strict mode");
225
0
}