mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +00:00
Implement object literal parsing; Instantiate classes from object literals
Essentially, if the contextual type is a class with a constructor that takes zero arguments or doesn't have a constructor at all, an object literal can be used to initialize a new instance of that class with preset values.
This commit is contained in:
parent
72cb1e9008
commit
9e508de69a
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,3 +1,3 @@
|
|||||||
bin/* text eol=lf
|
bin/* text eol=lf
|
||||||
dist/* -diff
|
dist/* binary
|
||||||
scripts/*.sh eol=lf
|
scripts/*.sh eol=lf
|
||||||
|
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
22
src/ast.ts
22
src/ast.ts
@ -432,6 +432,18 @@ export abstract class Node {
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static createObjectLiteralExpression(
|
||||||
|
names: IdentifierExpression[],
|
||||||
|
values: Expression[],
|
||||||
|
range: Range
|
||||||
|
): ObjectLiteralExpression {
|
||||||
|
var expr = new ObjectLiteralExpression();
|
||||||
|
expr.range = range;
|
||||||
|
expr.names = names;
|
||||||
|
expr.values = values;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
static createParenthesizedExpression(
|
static createParenthesizedExpression(
|
||||||
expression: Expression,
|
expression: Expression,
|
||||||
range: Range
|
range: Range
|
||||||
@ -1363,6 +1375,16 @@ export class NullExpression extends IdentifierExpression {
|
|||||||
text = "null";
|
text = "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Represents an object literal expression. */
|
||||||
|
export class ObjectLiteralExpression extends LiteralExpression {
|
||||||
|
literalKind = LiteralKind.OBJECT;
|
||||||
|
|
||||||
|
/** Field names. */
|
||||||
|
names: IdentifierExpression[];
|
||||||
|
/** Field values. */
|
||||||
|
values: Expression[];
|
||||||
|
}
|
||||||
|
|
||||||
/** Represents a parenthesized expression. */
|
/** Represents a parenthesized expression. */
|
||||||
export class ParenthesizedExpression extends Expression {
|
export class ParenthesizedExpression extends Expression {
|
||||||
kind = NodeKind.PARENTHESIZED;
|
kind = NodeKind.PARENTHESIZED;
|
||||||
|
@ -71,7 +71,11 @@ export enum CommonFlags {
|
|||||||
/** Is a virtual method. */
|
/** Is a virtual method. */
|
||||||
VIRTUAL = 1 << 26,
|
VIRTUAL = 1 << 26,
|
||||||
/** Is the main function. */
|
/** Is the main function. */
|
||||||
MAIN = 1 << 27
|
MAIN = 1 << 27,
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
QUOTED = 1 << 28
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Path delimiter inserted between file system levels. */
|
/** Path delimiter inserted between file system levels. */
|
||||||
|
@ -130,6 +130,7 @@ import {
|
|||||||
LiteralExpression,
|
LiteralExpression,
|
||||||
LiteralKind,
|
LiteralKind,
|
||||||
NewExpression,
|
NewExpression,
|
||||||
|
ObjectLiteralExpression,
|
||||||
ParenthesizedExpression,
|
ParenthesizedExpression,
|
||||||
PropertyAccessExpression,
|
PropertyAccessExpression,
|
||||||
TernaryExpression,
|
TernaryExpression,
|
||||||
@ -6144,7 +6145,10 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
assert(!implicitNegate);
|
assert(!implicitNegate);
|
||||||
return this.compileStaticString((<StringLiteralExpression>expression).value);
|
return this.compileStaticString((<StringLiteralExpression>expression).value);
|
||||||
}
|
}
|
||||||
// case LiteralKind.OBJECT:
|
case LiteralKind.OBJECT: {
|
||||||
|
assert(!implicitNegate);
|
||||||
|
return this.compileObjectLiteral(<ObjectLiteralExpression>expression, contextualType);
|
||||||
|
}
|
||||||
// case LiteralKind.REGEXP:
|
// case LiteralKind.REGEXP:
|
||||||
}
|
}
|
||||||
this.error(
|
this.error(
|
||||||
@ -6392,6 +6396,88 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compileObjectLiteral(expression: ObjectLiteralExpression, contextualType: Type): ExpressionRef {
|
||||||
|
var module = this.module;
|
||||||
|
|
||||||
|
// contextual type must be a class
|
||||||
|
var classReference = contextualType.classReference;
|
||||||
|
if (!classReference || classReference.is(CommonFlags.ABSTRACT)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Type_0_is_not_assignable_to_type_1,
|
||||||
|
expression.range, "<object>", contextualType.toString()
|
||||||
|
);
|
||||||
|
return module.createUnreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if present, check that the constructor is compatible with object literals
|
||||||
|
var ctor = classReference.constructorInstance;
|
||||||
|
if (ctor) {
|
||||||
|
if (ctor.signature.requiredParameters) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Constructor_of_class_0_must_not_require_any_arguments,
|
||||||
|
expression.range, classReference.toString()
|
||||||
|
);
|
||||||
|
return module.createUnreachable();
|
||||||
|
}
|
||||||
|
if (ctor.is(CommonFlags.PRIVATE)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration,
|
||||||
|
expression.range, classReference.toString()
|
||||||
|
);
|
||||||
|
return module.createUnreachable();
|
||||||
|
}
|
||||||
|
if (ctor.is(CommonFlags.PROTECTED)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration,
|
||||||
|
expression.range, classReference.toString()
|
||||||
|
);
|
||||||
|
return module.createUnreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check and compile field values
|
||||||
|
var names = expression.names;
|
||||||
|
var numNames = names.length;
|
||||||
|
var values = expression.values;
|
||||||
|
var members = classReference.members;
|
||||||
|
var hasErrors = false;
|
||||||
|
var exprs = new Array<ExpressionRef>(numNames + 2);
|
||||||
|
var tempLocal = this.currentFunction.getTempLocal(this.options.usizeType);
|
||||||
|
assert(numNames == values.length);
|
||||||
|
for (let i = 0, k = numNames; i < k; ++i) {
|
||||||
|
let member = members ? members.get(names[i].text) : null;
|
||||||
|
if (!member || member.kind != ElementKind.FIELD) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Property_0_does_not_exist_on_type_1,
|
||||||
|
names[i].range, names[i].text, classReference.toString()
|
||||||
|
);
|
||||||
|
hasErrors = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let type = (<Field>member).type;
|
||||||
|
exprs[i + 1] = this.module.createStore( // TODO: handle setters as well
|
||||||
|
type.byteSize,
|
||||||
|
this.module.createGetLocal(tempLocal.index, this.options.nativeSizeType),
|
||||||
|
this.compileExpression(values[i], (<Field>member).type, ConversionKind.IMPLICIT, WrapMode.NONE),
|
||||||
|
type.toNativeType(),
|
||||||
|
(<Field>member).memoryOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.currentType = classReference.type.nonNullableType;
|
||||||
|
if (hasErrors) return module.createUnreachable();
|
||||||
|
|
||||||
|
// allocate a new instance first and assign 'this' to the temp. local
|
||||||
|
exprs[0] = module.createSetLocal(
|
||||||
|
tempLocal.index,
|
||||||
|
compileBuiltinAllocate(this, classReference, expression)
|
||||||
|
);
|
||||||
|
|
||||||
|
// once all field values have been set, return 'this'
|
||||||
|
exprs[exprs.length - 1] = module.createGetLocal(tempLocal.index, this.options.nativeSizeType);
|
||||||
|
|
||||||
|
return module.createBlock(null, exprs, this.options.nativeSizeType);
|
||||||
|
}
|
||||||
|
|
||||||
compileNewExpression(expression: NewExpression, contextualType: Type): ExpressionRef {
|
compileNewExpression(expression: NewExpression, contextualType: Type): ExpressionRef {
|
||||||
var module = this.module;
|
var module = this.module;
|
||||||
var options = this.options;
|
var options = this.options;
|
||||||
|
@ -25,6 +25,7 @@ export enum DiagnosticCode {
|
|||||||
Duplicate_decorator = 213,
|
Duplicate_decorator = 213,
|
||||||
An_allocator_must_be_declared_to_allocate_memory_Try_importing_allocator_arena_or_allocator_tlsf = 214,
|
An_allocator_must_be_declared_to_allocate_memory_Try_importing_allocator_arena_or_allocator_tlsf = 214,
|
||||||
Optional_parameter_must_have_an_initializer = 215,
|
Optional_parameter_must_have_an_initializer = 215,
|
||||||
|
Constructor_of_class_0_must_not_require_any_arguments = 216,
|
||||||
Unterminated_string_literal = 1002,
|
Unterminated_string_literal = 1002,
|
||||||
Identifier_expected = 1003,
|
Identifier_expected = 1003,
|
||||||
_0_expected = 1005,
|
_0_expected = 1005,
|
||||||
@ -111,6 +112,8 @@ export enum DiagnosticCode {
|
|||||||
Expected_at_least_0_arguments_but_got_1 = 2555,
|
Expected_at_least_0_arguments_but_got_1 = 2555,
|
||||||
Expected_0_type_arguments_but_got_1 = 2558,
|
Expected_0_type_arguments_but_got_1 = 2558,
|
||||||
A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums = 2651,
|
A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums = 2651,
|
||||||
|
Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration = 2673,
|
||||||
|
Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration = 2674,
|
||||||
Namespace_0_has_no_exported_member_1 = 2694,
|
Namespace_0_has_no_exported_member_1 = 2694,
|
||||||
File_0_not_found = 6054,
|
File_0_not_found = 6054,
|
||||||
Numeric_separators_are_not_allowed_here = 6188,
|
Numeric_separators_are_not_allowed_here = 6188,
|
||||||
@ -138,6 +141,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
|||||||
case 213: return "Duplicate decorator.";
|
case 213: return "Duplicate decorator.";
|
||||||
case 214: return "An allocator must be declared to allocate memory. Try importing allocator/arena or allocator/tlsf.";
|
case 214: return "An allocator must be declared to allocate memory. Try importing allocator/arena or allocator/tlsf.";
|
||||||
case 215: return "Optional parameter must have an initializer.";
|
case 215: return "Optional parameter must have an initializer.";
|
||||||
|
case 216: return "Constructor of class '{0}' must not require any arguments.";
|
||||||
case 1002: return "Unterminated string literal.";
|
case 1002: return "Unterminated string literal.";
|
||||||
case 1003: return "Identifier expected.";
|
case 1003: return "Identifier expected.";
|
||||||
case 1005: return "'{0}' expected.";
|
case 1005: return "'{0}' expected.";
|
||||||
@ -224,6 +228,8 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
|||||||
case 2555: return "Expected at least {0} arguments, but got {1}.";
|
case 2555: return "Expected at least {0} arguments, but got {1}.";
|
||||||
case 2558: return "Expected {0} type arguments, but got {1}.";
|
case 2558: return "Expected {0} type arguments, but got {1}.";
|
||||||
case 2651: return "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.";
|
case 2651: return "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.";
|
||||||
|
case 2673: return "Constructor of class '{0}' is private and only accessible within the class declaration.";
|
||||||
|
case 2674: return "Constructor of class '{0}' is protected and only accessible within the class declaration.";
|
||||||
case 2694: return "Namespace '{0}' has no exported member '{1}'.";
|
case 2694: return "Namespace '{0}' has no exported member '{1}'.";
|
||||||
case 6054: return "File '{0}' not found.";
|
case 6054: return "File '{0}' not found.";
|
||||||
case 6188: return "Numeric separators are not allowed here.";
|
case 6188: return "Numeric separators are not allowed here.";
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"Duplicate decorator.": 213,
|
"Duplicate decorator.": 213,
|
||||||
"An allocator must be declared to allocate memory. Try importing allocator/arena or allocator/tlsf.": 214,
|
"An allocator must be declared to allocate memory. Try importing allocator/arena or allocator/tlsf.": 214,
|
||||||
"Optional parameter must have an initializer.": 215,
|
"Optional parameter must have an initializer.": 215,
|
||||||
|
"Constructor of class '{0}' must not require any arguments.": 216,
|
||||||
|
|
||||||
"Unterminated string literal.": 1002,
|
"Unterminated string literal.": 1002,
|
||||||
"Identifier expected.": 1003,
|
"Identifier expected.": 1003,
|
||||||
@ -105,6 +106,8 @@
|
|||||||
"Expected at least {0} arguments, but got {1}.": 2555,
|
"Expected at least {0} arguments, but got {1}.": 2555,
|
||||||
"Expected {0} type arguments, but got {1}.": 2558,
|
"Expected {0} type arguments, but got {1}.": 2558,
|
||||||
"A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": 2651,
|
"A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": 2651,
|
||||||
|
"Constructor of class '{0}' is private and only accessible within the class declaration.": 2673,
|
||||||
|
"Constructor of class '{0}' is protected and only accessible within the class declaration.": 2674,
|
||||||
"Namespace '{0}' has no exported member '{1}'.": 2694,
|
"Namespace '{0}' has no exported member '{1}'.": 2694,
|
||||||
|
|
||||||
"File '{0}' not found.": 6054,
|
"File '{0}' not found.": 6054,
|
||||||
|
@ -39,6 +39,8 @@ import {
|
|||||||
UnaryPostfixExpression,
|
UnaryPostfixExpression,
|
||||||
UnaryExpression,
|
UnaryExpression,
|
||||||
UnaryPrefixExpression,
|
UnaryPrefixExpression,
|
||||||
|
ClassExpression,
|
||||||
|
ObjectLiteralExpression,
|
||||||
|
|
||||||
Statement,
|
Statement,
|
||||||
BlockStatement,
|
BlockStatement,
|
||||||
@ -76,8 +78,7 @@ import {
|
|||||||
ParameterNode,
|
ParameterNode,
|
||||||
ParameterKind,
|
ParameterKind,
|
||||||
ExportMember,
|
ExportMember,
|
||||||
SwitchCase,
|
SwitchCase
|
||||||
ClassExpression
|
|
||||||
} from "../ast";
|
} from "../ast";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -411,7 +412,8 @@ export class ASTBuilder {
|
|||||||
// expressions
|
// expressions
|
||||||
|
|
||||||
visitIdentifierExpression(node: IdentifierExpression): void {
|
visitIdentifierExpression(node: IdentifierExpression): void {
|
||||||
this.sb.push(node.text);
|
if (node.is(CommonFlags.QUOTED)) this.visitStringLiteral(node.text);
|
||||||
|
else this.sb.push(node.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitArrayLiteralExpression(node: ArrayLiteralExpression): void {
|
visitArrayLiteralExpression(node: ArrayLiteralExpression): void {
|
||||||
@ -429,6 +431,33 @@ export class ASTBuilder {
|
|||||||
sb.push("]");
|
sb.push("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visitObjectLiteralExpression(node: ObjectLiteralExpression): void {
|
||||||
|
var sb = this.sb;
|
||||||
|
var names = node.names;
|
||||||
|
var values = node.values;
|
||||||
|
var numElements = names.length;
|
||||||
|
assert(numElements == values.length);
|
||||||
|
if (numElements) {
|
||||||
|
sb.push("{\n");
|
||||||
|
indent(sb, ++this.indentLevel);
|
||||||
|
this.visitNode(names[0]);
|
||||||
|
sb.push(": ");
|
||||||
|
this.visitNode(values[0]);
|
||||||
|
for (let i = 1; i < numElements; ++i) {
|
||||||
|
sb.push(",\n");
|
||||||
|
indent(sb, this.indentLevel);
|
||||||
|
this.visitNode(names[i]);
|
||||||
|
sb.push(": ");
|
||||||
|
this.visitNode(values[i]);
|
||||||
|
}
|
||||||
|
sb.push("\n");
|
||||||
|
indent(sb, --this.indentLevel);
|
||||||
|
sb.push("}");
|
||||||
|
} else {
|
||||||
|
sb.push("{}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
visitAssertionExpression(node: AssertionExpression): void {
|
visitAssertionExpression(node: AssertionExpression): void {
|
||||||
var sb = this.sb;
|
var sb = this.sb;
|
||||||
if (node.assertionKind == AssertionKind.PREFIX) {
|
if (node.assertionKind == AssertionKind.PREFIX) {
|
||||||
@ -542,10 +571,10 @@ export class ASTBuilder {
|
|||||||
this.visitArrayLiteralExpression(<ArrayLiteralExpression>node);
|
this.visitArrayLiteralExpression(<ArrayLiteralExpression>node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// case LiteralKind.OBJECT: {
|
case LiteralKind.OBJECT: {
|
||||||
// this.serializeObjectLiteralExpression(<ObjectLiteralExpression>node);
|
this.visitObjectLiteralExpression(<ObjectLiteralExpression>node);
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
default: {
|
default: {
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
|
@ -3073,6 +3073,51 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
return Node.createArrayLiteralExpression(elementExpressions, tn.range(startPos, tn.pos));
|
return Node.createArrayLiteralExpression(elementExpressions, tn.range(startPos, tn.pos));
|
||||||
}
|
}
|
||||||
|
// ObjectLiteralExpression
|
||||||
|
case Token.OPENBRACE: {
|
||||||
|
let startPos = tn.tokenPos;
|
||||||
|
let names = new Array<IdentifierExpression>();
|
||||||
|
let values = new Array<Expression>();
|
||||||
|
let name: IdentifierExpression;
|
||||||
|
while (!tn.skip(Token.CLOSEBRACE)) {
|
||||||
|
if (!tn.skipIdentifier()) {
|
||||||
|
if (!tn.skip(Token.STRINGLITERAL)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Identifier_expected,
|
||||||
|
tn.range(),
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
name = Node.createIdentifierExpression(tn.readString(), tn.range());
|
||||||
|
name.set(CommonFlags.QUOTED);
|
||||||
|
} else {
|
||||||
|
name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
|
||||||
|
}
|
||||||
|
if (!tn.skip(Token.COLON)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode._0_expected,
|
||||||
|
tn.range(), ":"
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let value = this.parseExpression(tn, Precedence.COMMA + 1);
|
||||||
|
if (!value) return null;
|
||||||
|
names.push(name);
|
||||||
|
values.push(value);
|
||||||
|
if (!tn.skip(Token.COMMA)) {
|
||||||
|
if (tn.skip(Token.CLOSEBRACE)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode._0_expected,
|
||||||
|
tn.range(), "}"
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Node.createObjectLiteralExpression(names, values, tn.range(startPos, tn.pos));
|
||||||
|
}
|
||||||
// AssertionExpression (unary prefix)
|
// AssertionExpression (unary prefix)
|
||||||
case Token.LESSTHAN: {
|
case Token.LESSTHAN: {
|
||||||
let toType = this.parseType(tn);
|
let toType = this.parseType(tn);
|
||||||
|
326
tests/compiler/object-literal.optimized.wat
Normal file
326
tests/compiler/object-literal.optimized.wat
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
(module
|
||||||
|
(type $ii (func (param i32) (result i32)))
|
||||||
|
(type $iv (func (param i32)))
|
||||||
|
(type $iiiiv (func (param i32 i32 i32 i32)))
|
||||||
|
(type $iii (func (param i32 i32) (result i32)))
|
||||||
|
(type $iiii (func (param i32 i32 i32) (result i32)))
|
||||||
|
(type $v (func))
|
||||||
|
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
|
||||||
|
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||||
|
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||||
|
(global $HEAP_BASE i32 (i32.const 76))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 8) "\0b\00\00\00h\00e\00l\00l\00o\00 \00w\00o\00r\00l\00d")
|
||||||
|
(data (i32.const 36) "\11\00\00\00o\00b\00j\00e\00c\00t\00-\00l\00i\00t\00e\00r\00a\00l\00.\00t\00s")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start)
|
||||||
|
(func $~lib/allocator/arena/allocate_memory (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(local $1 i32)
|
||||||
|
(local $2 i32)
|
||||||
|
(local $3 i32)
|
||||||
|
(if
|
||||||
|
(get_local $0)
|
||||||
|
(block
|
||||||
|
(if
|
||||||
|
(i32.gt_u
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1073741824)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.gt_u
|
||||||
|
(tee_local $0
|
||||||
|
(i32.and
|
||||||
|
(i32.add
|
||||||
|
(i32.add
|
||||||
|
(tee_local $1
|
||||||
|
(get_global $~lib/allocator/arena/offset)
|
||||||
|
)
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.const 7)
|
||||||
|
)
|
||||||
|
(i32.const -8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.shl
|
||||||
|
(tee_local $2
|
||||||
|
(current_memory)
|
||||||
|
)
|
||||||
|
(i32.const 16)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.lt_s
|
||||||
|
(grow_memory
|
||||||
|
(select
|
||||||
|
(get_local $2)
|
||||||
|
(tee_local $3
|
||||||
|
(i32.shr_u
|
||||||
|
(i32.and
|
||||||
|
(i32.add
|
||||||
|
(i32.sub
|
||||||
|
(get_local $0)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
(i32.const 65535)
|
||||||
|
)
|
||||||
|
(i32.const -65536)
|
||||||
|
)
|
||||||
|
(i32.const 16)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.gt_s
|
||||||
|
(get_local $2)
|
||||||
|
(get_local $3)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.lt_s
|
||||||
|
(grow_memory
|
||||||
|
(get_local $3)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $~lib/allocator/arena/offset
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(func $~lib/memory/compare_memory (; 2 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||||
|
(if
|
||||||
|
(i32.eq
|
||||||
|
(get_local $0)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(loop $continue|0
|
||||||
|
(if
|
||||||
|
(if (result i32)
|
||||||
|
(get_local $2)
|
||||||
|
(i32.eq
|
||||||
|
(i32.load8_u
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.load8_u
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $2)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(set_local $2
|
||||||
|
(i32.sub
|
||||||
|
(get_local $2)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $0
|
||||||
|
(i32.add
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $1
|
||||||
|
(i32.add
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue|0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(tee_local $0
|
||||||
|
(if (result i32)
|
||||||
|
(get_local $2)
|
||||||
|
(i32.sub
|
||||||
|
(i32.load8_u
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.load8_u
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $~lib/string/String.__eq (; 3 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||||
|
(local $2 i32)
|
||||||
|
(if
|
||||||
|
(i32.eq
|
||||||
|
(get_local $0)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(tee_local $2
|
||||||
|
(i32.eqz
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $2
|
||||||
|
(i32.eqz
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(get_local $2)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.ne
|
||||||
|
(tee_local $2
|
||||||
|
(i32.load
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.load
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.eqz
|
||||||
|
(call $~lib/memory/compare_memory
|
||||||
|
(i32.add
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
(i32.add
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
(i32.shl
|
||||||
|
(get_local $2)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $object-literal/bar (; 4 ;) (type $iv) (param $0 i32)
|
||||||
|
(if
|
||||||
|
(i32.ne
|
||||||
|
(i32.load
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call $~lib/env/abort
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 36)
|
||||||
|
(i32.const 9)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(call $~lib/string/String.__eq
|
||||||
|
(i32.load offset=4
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call $~lib/env/abort
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 36)
|
||||||
|
(i32.const 10)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $object-literal/bar2 (; 5 ;) (type $iv) (param $0 i32)
|
||||||
|
(if
|
||||||
|
(i32.ne
|
||||||
|
(i32.load
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call $~lib/env/abort
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 36)
|
||||||
|
(i32.const 23)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $start (; 6 ;) (type $v)
|
||||||
|
(local $0 i32)
|
||||||
|
(set_global $~lib/allocator/arena/startOffset
|
||||||
|
(i32.and
|
||||||
|
(i32.add
|
||||||
|
(get_global $HEAP_BASE)
|
||||||
|
(i32.const 7)
|
||||||
|
)
|
||||||
|
(i32.const -8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $~lib/allocator/arena/offset
|
||||||
|
(get_global $~lib/allocator/arena/startOffset)
|
||||||
|
)
|
||||||
|
(i32.store
|
||||||
|
(tee_local $0
|
||||||
|
(call $~lib/allocator/arena/allocate_memory
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(i32.store offset=4
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
(call $object-literal/bar
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.store
|
||||||
|
(tee_local $0
|
||||||
|
(call $~lib/allocator/arena/allocate_memory
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(call $object-literal/bar2
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
26
tests/compiler/object-literal.ts
Normal file
26
tests/compiler/object-literal.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import "allocator/arena";
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
bar: i32;
|
||||||
|
baz: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bar(foo: Foo): void {
|
||||||
|
assert(foo.bar == 1);
|
||||||
|
assert(foo.baz == "hello world");
|
||||||
|
}
|
||||||
|
|
||||||
|
bar({ bar: 1, baz: "hello world" });
|
||||||
|
|
||||||
|
class Foo2 {
|
||||||
|
bar: i32;
|
||||||
|
constructor() {
|
||||||
|
this.bar = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bar2(foo: Foo2): void {
|
||||||
|
assert(foo.bar == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bar2({ bar: 2 });
|
369
tests/compiler/object-literal.untouched.wat
Normal file
369
tests/compiler/object-literal.untouched.wat
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
(module
|
||||||
|
(type $ii (func (param i32) (result i32)))
|
||||||
|
(type $iv (func (param i32)))
|
||||||
|
(type $iiiiv (func (param i32 i32 i32 i32)))
|
||||||
|
(type $iii (func (param i32 i32) (result i32)))
|
||||||
|
(type $iiii (func (param i32 i32 i32) (result i32)))
|
||||||
|
(type $v (func))
|
||||||
|
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
|
||||||
|
(global $~lib/internal/allocator/AL_BITS i32 (i32.const 3))
|
||||||
|
(global $~lib/internal/allocator/AL_SIZE i32 (i32.const 8))
|
||||||
|
(global $~lib/internal/allocator/AL_MASK i32 (i32.const 7))
|
||||||
|
(global $~lib/internal/allocator/MAX_SIZE_32 i32 (i32.const 1073741824))
|
||||||
|
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
|
||||||
|
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
|
||||||
|
(global $~lib/internal/string/HEADER_SIZE i32 (i32.const 4))
|
||||||
|
(global $HEAP_BASE i32 (i32.const 76))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 8) "\0b\00\00\00h\00e\00l\00l\00o\00 \00w\00o\00r\00l\00d\00")
|
||||||
|
(data (i32.const 36) "\11\00\00\00o\00b\00j\00e\00c\00t\00-\00l\00i\00t\00e\00r\00a\00l\00.\00t\00s\00")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start)
|
||||||
|
(func $~lib/allocator/arena/allocate_memory (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(local $1 i32)
|
||||||
|
(local $2 i32)
|
||||||
|
(local $3 i32)
|
||||||
|
(local $4 i32)
|
||||||
|
(local $5 i32)
|
||||||
|
(local $6 i32)
|
||||||
|
(if
|
||||||
|
(get_local $0)
|
||||||
|
(block
|
||||||
|
(if
|
||||||
|
(i32.gt_u
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1073741824)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(set_local $1
|
||||||
|
(get_global $~lib/allocator/arena/offset)
|
||||||
|
)
|
||||||
|
(set_local $2
|
||||||
|
(i32.and
|
||||||
|
(i32.add
|
||||||
|
(i32.add
|
||||||
|
(get_local $1)
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.const 7)
|
||||||
|
)
|
||||||
|
(i32.xor
|
||||||
|
(i32.const 7)
|
||||||
|
(i32.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $3
|
||||||
|
(current_memory)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.gt_u
|
||||||
|
(get_local $2)
|
||||||
|
(i32.shl
|
||||||
|
(get_local $3)
|
||||||
|
(i32.const 16)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(set_local $4
|
||||||
|
(i32.shr_u
|
||||||
|
(i32.and
|
||||||
|
(i32.add
|
||||||
|
(i32.sub
|
||||||
|
(get_local $2)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
(i32.const 65535)
|
||||||
|
)
|
||||||
|
(i32.xor
|
||||||
|
(i32.const 65535)
|
||||||
|
(i32.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.const 16)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $5
|
||||||
|
(select
|
||||||
|
(tee_local $5
|
||||||
|
(get_local $3)
|
||||||
|
)
|
||||||
|
(tee_local $6
|
||||||
|
(get_local $4)
|
||||||
|
)
|
||||||
|
(i32.gt_s
|
||||||
|
(get_local $5)
|
||||||
|
(get_local $6)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.lt_s
|
||||||
|
(grow_memory
|
||||||
|
(get_local $5)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.lt_s
|
||||||
|
(grow_memory
|
||||||
|
(get_local $4)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $~lib/allocator/arena/offset
|
||||||
|
(get_local $2)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(func $~lib/memory/compare_memory (; 2 ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
|
||||||
|
(if
|
||||||
|
(i32.eq
|
||||||
|
(get_local $0)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block $break|0
|
||||||
|
(loop $continue|0
|
||||||
|
(if
|
||||||
|
(if (result i32)
|
||||||
|
(get_local $2)
|
||||||
|
(i32.eq
|
||||||
|
(i32.load8_u
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.load8_u
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $2)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(block
|
||||||
|
(set_local $2
|
||||||
|
(i32.sub
|
||||||
|
(get_local $2)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $0
|
||||||
|
(i32.add
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $1
|
||||||
|
(i32.add
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue|0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if (result i32)
|
||||||
|
(get_local $2)
|
||||||
|
(i32.sub
|
||||||
|
(i32.load8_u
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.load8_u
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $~lib/string/String.__eq (; 3 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
|
||||||
|
(local $2 i32)
|
||||||
|
(local $3 i32)
|
||||||
|
(if
|
||||||
|
(i32.eq
|
||||||
|
(get_local $0)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(if (result i32)
|
||||||
|
(tee_local $2
|
||||||
|
(i32.eq
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $2)
|
||||||
|
(i32.eq
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_local $3
|
||||||
|
(i32.load
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.ne
|
||||||
|
(get_local $3)
|
||||||
|
(i32.load
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.eqz
|
||||||
|
(call $~lib/memory/compare_memory
|
||||||
|
(i32.add
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
(i32.add
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
(i32.shl
|
||||||
|
(get_local $3)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $object-literal/bar (; 4 ;) (type $iv) (param $0 i32)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(i32.eq
|
||||||
|
(i32.load
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call $~lib/env/abort
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 36)
|
||||||
|
(i32.const 9)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(call $~lib/string/String.__eq
|
||||||
|
(i32.load offset=4
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call $~lib/env/abort
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 36)
|
||||||
|
(i32.const 10)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $object-literal/bar2 (; 5 ;) (type $iv) (param $0 i32)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(i32.eq
|
||||||
|
(i32.load
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call $~lib/env/abort
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 36)
|
||||||
|
(i32.const 23)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $start (; 6 ;) (type $v)
|
||||||
|
(local $0 i32)
|
||||||
|
(local $1 i32)
|
||||||
|
(set_global $~lib/allocator/arena/startOffset
|
||||||
|
(i32.and
|
||||||
|
(i32.add
|
||||||
|
(get_global $HEAP_BASE)
|
||||||
|
(i32.const 7)
|
||||||
|
)
|
||||||
|
(i32.xor
|
||||||
|
(i32.const 7)
|
||||||
|
(i32.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $~lib/allocator/arena/offset
|
||||||
|
(get_global $~lib/allocator/arena/startOffset)
|
||||||
|
)
|
||||||
|
(call $object-literal/bar
|
||||||
|
(block (result i32)
|
||||||
|
(set_local $0
|
||||||
|
(call $~lib/allocator/arena/allocate_memory
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.store
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(i32.store offset=4
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call $object-literal/bar2
|
||||||
|
(block (result i32)
|
||||||
|
(set_local $1
|
||||||
|
(call $~lib/allocator/arena/allocate_memory
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.store
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(get_local $1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
9
tests/parser/object-literal.ts
Normal file
9
tests/parser/object-literal.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
var obj = {
|
||||||
|
a: 123,
|
||||||
|
b: "234",
|
||||||
|
"c": false,
|
||||||
|
d: {
|
||||||
|
a: 123,
|
||||||
|
"b": {}
|
||||||
|
}
|
||||||
|
};
|
9
tests/parser/object-literal.ts.fixture.ts
Normal file
9
tests/parser/object-literal.ts.fixture.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
var obj = {
|
||||||
|
a: 123,
|
||||||
|
b: "234",
|
||||||
|
"c": false,
|
||||||
|
d: {
|
||||||
|
a: 123,
|
||||||
|
"b": {}
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user